Базовая работа с PHP CURL: GET, POST, JSON, Headers

Базовая работа с PHP CURL: GET, POST, JSON, Headers

Curl - это программное обеспечение, которое позволяет выполнять запросы разных типов или протоколов. И как раз cURL помогает нам писать боты и парcеры на PHP, автоматизируя шаблонные HTTP-запросы, и собирая большое количество данных автоматизировано. PHP имеет встроенные инструменты по удобной работе с cURL. И в этой статье я покажу несколько полезных примеров как работать с CURL в PHP.

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

PHP cURL основы

curl_init(); // инициализирует сессию работы с cURL
curl_setopt(...); // изменяет поведение cURL-сессии, в соответствии с переданными опциями
curl_exec(); // выполняет cURL запрос по сконфигурированной сессии, и возвращает результат
curl_close(); // закрывает сессию cURL и удаляет переменную, которой присвоен curl_init();

  • curl_init ([ string $url = NULL ] ) - с него начинается инициализация сессии cURL
  • curl_setopt ( resource $ch , int $option , mixed $value ) - конфигурирование настроек текущей сессии cURL
  • curl_exec ( resource $ch ) - выполняем запрос, получаем результат
  • curl_close ( resource $ch ) - закрытие сессии. В реальности, можно игнорировать выполнение curl_close(), так как PHP сделает это за нас, после выполнения скрипта

Отправка GET запроса из PHP cURL

Здесь всё просто, PHP cURL GET запрос - это самое простое, что можно придумать.

// URL страницы, которую открываем
$url = 'https://badcode.ru';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

В результате выполнения этого кода, переменной $response будет присвоен ответ от сервера, к которому мы стучались (в основном - это HTML или JSON).

Иногда стоит необходимость отправки GET-запроса, формируя URL-адрес из Query-параметров. Для таких случаев, можете воспользоваться встроенной PHP-функцией, формирующей URL-строку с параметрами из массива:

$queryParams = [
    'page' => 1,
    'user' => 'truehero',
];

$url = 'https://badcode.ru?' . http_build_query($queryParams);
echo $url; // https://badcode.ru?page=1&user=truehero

// curl_init($url); ... curl_exec(); ...

Теперь вы знаете, как склеить массив данных в URL из PHP.

Отправка POST запроса из PHP cURL

PHP cURL POST запрос обычно не выполняется с пустым телом. Запрос этого типа считается запросом на добавление данных (создание новой сущности в БД, к примеру) и обычно нам необходимо передавать серверу набор каких-то данных. Код отправки POST-запроса с передачей данных будет выглядеть так:

// данные POST-запроса
$data = [
    'event' => 'Page',
    'url' => 'http://badcode.ru'
];

// url, на который отправляет данные
$url = 'https://badcode.ru/log_analitycs';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST-параметры, указанные в массиве, в веде ключ => значение

$response = curl_exec($ch);

curl_close($ch);

var_dump($response);

// если данные от API получаем в JSON, то, декодируем их
$result = json_decode($response, true); // ['success': true, ...]

Отправка cURL запроса из PHP с собственными заголовками (PHP cURL Headers)

Для того, чтобы передать дополнительные, собственные заголовки, нужно с помощью функции curl_setopt() задать опцию CURLOPT_HTTPHEADER, передав массив заголовков в формате Name: Header value:

curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Custom-Header-1: The-Header-Value-1',
    'Custom-Header-1: The-Header-Value-2'
]);

Отправка POST JSON запроса в PHP cURL

Очень часто, при написании ботов, имитирующих взаимодействие с API, приходится отправлять данные на целевой сервер в формате JSON. И так сложилось, что отправка Form-Data POST параметров отличается от алгоритма отправки JSON данных, потому, и передавать эти данные для cURL нужно по-другому.

Для того, чтобы корректно передать данные в формате JSON через PHP cURL, необходимо исходный массив с параметрами, перекодировать в JSON вручную, и заполнить этими данными тело (body) запроса. А так же, чтобы сервер понял, что это данные в формате JSON, нужно передать соответствующие HTTP-заголовки (о которых мы говорили выше).

$data = [
    'site' => 'https://badcode.ru',
    'action' => 'subscribe',
    'email' => 'bafisto@bigmir.net',
];
$dataString = json_encode($data);

$url = 'http://localhost/handler.php';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($dataString)
]);

$result = curl_exec($ch);
curl_close($ch);

Если вы хотите протестировать корректность отправки данных в "принимающем" PHP-скрипте, то данные нужно считывать не с массива $_POST, а с тела запроса. И для этого, нужно выполнить код:

$data = json_decode(file_get_contents('php://input'), true);

Основной принцип передачи данных в JSON с помощью CURL заключается в том, что нужно выполнить POST запрос, тело которого заполнить закодированными в JSON данными, после чего, указать соответствующий заголовок позволяющий серверу понять, что ему на обработку пришли JSON данные.

Резюме

Работа всех этих опций, их работа и настройка подробно рассказано в этой статье. А так же, на закрепление этого материала, в следующей статье был изложен алгоритм написания ботов на PHP, советую почитать, и попробовать написать собственного бота, чтобы полноценно разобраться в этой теме. Эта статья охватывает большинство важных тем: отправка POST-запросов, обработка ответов, имитация браузера из PHP.

А если так сложилось, что на вашем хостинге недоступен cURL, то можете воспользоваться востроенным инстурументом file_get_contents(), написание ботов на котором было описыно в этой статье, который позволит выполнить HTTP-запросы и получить контент с удалённого сервера без cURL.