Статьи

Использование cURL для удаленных запросов

Если вы пользователь Linux, то вы, вероятно, использовали cURL. Это мощный инструмент, который используется для отправки писем и загрузки последних субтитров My Little Pony. В этой статье я объясню, как использовать расширение cURL в PHP. Расширение предлагает нам функциональность консоли в удобном мире PHP. Я расскажу об отправке запросов GET и POST, обработке файлов cookie для входа в систему и функциональности FTP.

Прежде чем мы начнем, убедитесь, что у вас установлено расширение (и библиотека libcURL). Он не установлен по умолчанию. В большинстве случаев его можно установить с помощью диспетчера пакетов вашей системы, но, кроме этого, вы можете найти инструкции в руководстве по PHP.

Как это работает?

Все запросы cURL следуют одному и тому же базовому шаблону:

  1. Сначала мы инициализируем ресурс cURL (часто сокращенно обозначаемый как ch для «дескриптора cURL»), вызывая curl_init()
  2. Затем мы устанавливаем различные параметры, такие как URL, метод запроса, данные полезной нагрузки и т. Д. Параметры могут быть установлены индивидуально с помощью curl_setopt()curl_setopt_array()
  3. Затем мы выполняем запрос, вызывая curl_exec()
  4. Наконец, мы освобождаем ресурс для очистки памяти.

Итак, стандартный код для запроса выглядит примерно так:

 <?php
// init the resource
$ch = curl_init();

// set a single option...
curl_setopt($ch, OPTION, $value);
// ... or an array of options
curl_setopt_array($ch, array(
OPTION1 => $value1,
OPTION2 => $value2
));

// execute
$output = curl_exec($ch);

// free
curl_close($ch);

Единственное, что изменяется для запроса, это то, какие параметры установлены, что, конечно, зависит от того, что вы делаете с cURL.

Получить веб-страницу

Самый простой пример использования cURL, о котором я могу подумать, — это просто загрузка содержимого веб-страницы. Итак, давайте для примера приведем домашнюю страницу BBC.

 <?php
curl_setopt_array(
$ch, array(
CURLOPT_URL => 'http://www.bbc.co.uk/',
CURLOPT_RETURNTRANSFER => true
));

$output = curl_exec($ch);
echo $output;

Проверьте вывод в вашем браузере, и вы должны увидеть веб-сайт BBC. Нам повезло, так как сайт отображается правильно из-за его абсолютной ссылки на таблицы стилей и изображения.

Варианты, которые мы только что использовали:

  • CURLOPT_URL
  • CURLOPT_RETURNTRANSFERcurl_exec() Если установлено значение true, curl_exec()

Войти на сайт

cURL выполнил запрос GET для получения страницы BBC, но cURL также может использовать другие методы, такие как POST и PUT. В этом примере давайте смоделируем вход на веб-сайт на платформе WordPress. Вход в систему осуществляется путем отправки запроса POST на http://example.com/wp-login.php со следующими данными:

  • login
  • pwd
  • redirect_to
  • testcookie

Конечно, эти параметры специфичны для каждого сайта. Вы всегда должны проверять входные имена сами, что легко можно сделать, просмотрев источник HTML-страницы в вашем браузере.

 <?php
$postData = array(
'login' => 'acogneau',
'pwd' => 'secretpassword',
'redirect_to' => 'http://example.com',
'testcookie' => '1'
);

curl_setopt_array($ch, array(
CURLOPT_URL => 'http://example.com/wp-login.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_FOLLOWLOCATION => true
));

$output = curl_exec($ch);
echo $output;

Новые опции:

  • CURLOPT_POST
  • CURLOPT_POSTFIELDS
  • CURLOPT_FOLLOWLOCATION

Ой! Однако, если вы протестируете вышеизложенное, вы увидите сообщение об ошибке: «ОШИБКА: файлы cookie заблокированы или не поддерживаются вашим браузером. Вы должны разрешить использование файлов cookie для WordPress ». Это нормально, потому что для работы сеансов нам необходимо включить файлы cookie. Мы делаем это, добавляя еще две опции.

 <?php
curl_setopt_array($ch, array(
CURLOPT_URL => 'http://example.com/wp-login.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIESESSION => true,
CUROPT_COOKIEJAR => 'cookie.txt'
));

Новые опции:

  • CURLOPT_COOKIESESSION
  • CURLOPT_COOKIEJAR Убедитесь, что у вас есть правильные разрешения для записи в файл!

Теперь, когда мы вошли в систему, нам нужно только сослаться на файл cookie для последующих запросов.

Работа с FTP

Использование cURL для загрузки и выгрузки файлов через FTP также очень просто. Давайте посмотрим на скачивание файла:

 <?php
curl_setopt_array($ch, array(
CURLOPT_URL => 'ftp://ftp.example.com/test.txt',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'username:password'
));

$output = curl_exec($ch);
echo $output;

Обратите внимание, что не так много общедоступных FTP-серверов, которые разрешают анонимную загрузку и загрузку по соображениям безопасности, поэтому приведенные выше URL и учетные данные являются просто заполнителями.

Это почти то же самое, что отправка HTTP-запроса, но есть только несколько незначительных отличий:

  • CURLOPT_URL
  • CURLOT_USERPWD

Загрузка файла через FTP немного сложнее, но все же управляема. Это выглядит так:

 <?php
$fp = fopen('test.txt', 'r');
curl_setopt_array($ch, array(
CURLOPT_URL => 'ftp://ftp.example.com/test.txt',
CURLOPT_USERPWD => 'username:password'
CURLOPT_UPLOAD => true,
CURLOPT_INFILE => $fp,
CURLOPT_INFILESIZE => filesize('test.txt')
));
curl_exec($ch);

fclose($fp);
curl_close($ch);

Важные варианты здесь:

  • CURLOPT_UPLOAD
  • CURLOPT_INFILE
  • CURLOPT_INFILESIZE

Отправка нескольких запросов

Представьте, что нам нужно выполнить пять запросов, чтобы получить все необходимые данные. Имейте в виду, что некоторые вещи будут вне нашего контроля, такие как задержка в сети и скорость отклика целевых серверов. Тогда должно быть очевидно, что любые задержки при выполнении пяти последовательных вызовов могут действительно накапливаться! Один из способов решить эту проблему — выполнять запросы асинхронно.

Асинхронные методы более распространены в сообществах JavaScript и Node.js, но вкратце, вместо того, чтобы ждать трудоемкой задачи, которую мы выполняем, мы назначаем задачу другому потоку или процессу и тем временем продолжаем делать другие вещи. Когда задача выполнена, мы возвращаемся к ее результату. Важно то, что мы не потратили впустую время, ожидая результата; мы потратили его на выполнение другого кода самостоятельно.

Подход для выполнения нескольких асинхронных запросов cURL немного отличается от предыдущего. Мы начинаем то же самое — мы запускаем каждый канал и затем устанавливаем параметры — но затем мы запускаем мультипроцессор using curl_multi_init()curl_multi_add_handle() Мы выполняем обработчики, просматривая их и проверяя их состояние. В конце мы получаем содержимое ответа с помощью curl_multi_getcontent()

 <?php
// URLs we want to retrieve
$urls = array(
'http://www.google.com',
'http://www.bing.com',
'http://www.yahoo.com',
'http://www.twitter.com',
'http://www.facebook.com'
);

// initialize the multihandler
$mh = curl_multi_init();

$channels = array();
foreach ($urls as $key => $url) {
// initiate individual channel
$channels[$key] = curl_init();
curl_setopt_array($channels[$key], array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true
));

// add channel to multihandler
curl_multi_add_handle($mh, $channels[$key]);
}

// execute - if there is an active connection then keep looping
$active = null;
do {
$status = curl_multi_exec($mh, $active);
}
while ($active && $status == CURLM_OK);

// echo the content, remove the handlers, then close them
foreach ($channels as $chan) {
echo curl_multi_getcontent($chan);
curl_multi_remove_handle($mh, $chan);
curl_close($chan);
}

// close the multihandler
curl_multi_close($mh);

Приведенный выше код потребовал около 1100 мс для выполнения на моем ноутбуке. Последовательное выполнение запросов без мультиинтерфейса заняло около 2000 мс. Представьте, какой будет ваша выгода, если вы отправите сотни запросов!

Существует несколько проектов, которые абстрагируют и оборачивают мультиинтерфейс Обсуждение их выходит за рамки статьи, но если вы планируете выполнять несколько запросов асинхронно, то я рекомендую вам взглянуть на них:

Исправление проблем

Если вы используете cURL, вы, вероятно, выполняете свои запросы к сторонним серверам. Вы не можете управлять ими, и многое может пойти не так: серверы могут отключиться, структуры каталогов могут измениться и т. Д. Нам нужен эффективный способ выяснить, что не так, когда что-то не работает, и, к счастью, cURL предлагает две функции для этого: curl_getinfo()curl_error()

curl_getinfo()

 <?php
var_dump(curl_getinfo($ch));

Если появляется ошибка, вы можете проверить ее с помощью curl_error()

 <?php
if (!curl_exec($ch)) {
// if curl_exec() returned false and thus failed
echo 'An error has occurred: ' . curl_error($ch);
}
else {
echo 'everything was successful';
}

Вывод

cURL предлагает мощный и эффективный способ выполнять удаленные вызовы, поэтому, если вам когда-либо понадобится сканер или что-то для доступа к внешнему API, cURL — отличный инструмент для работы. Он предоставляет нам приятный интерфейс и относительно простой способ выполнения запросов. Для получения дополнительной информации ознакомьтесь с Руководством по PHP и веб-сайтом cURL . Увидимся в следующий раз!

Комментарии к этой статье закрыты. Есть вопрос по PHP? Почему бы не спросить об этом на наших форумах ?

Изображение через Fotolia