В статье рассмотрены пример использования библиотеки cURL необходимой для передачи данных по протоколам HTTP, HTTPS, FTP. cURL - клиентская библиотека работы с URL, используется в языке PHP для передачи и получения различных данных форматах, JSON, XML, обычном HTML, а так же получения, парсинга и загрузки файлов. 

В общем виде работа cURL выглядит так: Инициализация сеанса -> Настройка запроса -> Выполнение запроса -> Закрытие сеанса. 

Настройки запроса cURL

Для настройки запроса существует набор специальных параметров, а именно:

  • CURLOPT_RETURNTRANSFER - вернуть ответ в виде строки, вместо того, чтобы показывать его сразу
  • CURLOPT_CONNECTTIMEOUT - сколько по времени ждать ответа
  • CURLOPT_TIMEOUT - сколько секунд будет выполняться cURL запрос
  • CURLOPT_USERAGENT- headers (заголовки) для запроса
  • CURLOPT_URL - URL куда будет отправлен запрос
  • CURLOPT_POST - отправить POST запрос
  • CURLOPT_POSTFIELDS - массив POST полей к запросу

Функции cURL

Основные функции которыми вам придётся пользоваться во время работы:
  • curl_init() - открывает сеанс cURL
  • curl_close() - закрывает сеанс cURL
  • curl_exec() - выполняет запрос
И так, давайте рассмотрим самые частые случаи использования этой замечательной библиотеки.

GET запрос

Получаем страницу сайта

//Инициализация сеанса
$ch = curl_init('https://site.com');

//Установка параметров
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

//Выполнение
$html = curl_exec($ch);

//Закрытие сеанса
curl_close($ch);

//Работа с полученными данными 
echo $html;

GET запрос с параметрами

Теперь передадим пару параметров

//Подготовка массива спараметрами
$getParams = [
	'name'  => 'Max',
	'age' => '21'
];
 
$ch = curl_init('https://site.com?' . http_build_query($getParams));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$html = curl_exec($ch);

curl_close($ch);

echo $html;

POST запрос


//Допустим отправлям оценку (количество звёзд) этому материалу
$arr = [
	'post_id'    => '123',
	'stars' => '5'
];		
 
$ch = curl_init('https://site.com');
curl_setopt($ch, CURLOPT_POST, 1); //Этой опцией мы указали, что запрос должен быть выполнен методом POST
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arr, '', '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$html = curl_exec($ch);

curl_close($ch);	
 
echo $html;

Отправка JSON средствами POST и cURL


//Подготовка данных
$user = [
	'user'  => 'Max',
	'age' => 25,
	'position' => 'Manger'
];		
 
$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($user, JSON_UNESCAPED_UNICODE)); //Конвертируем данные в JSON
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$res = curl_exec($ch);

curl_close($ch);

//Обратная конвертация (ответ так же получен в формате JSON)
$res = json_decode($res, true);

//Удобно просматриваем массив
echo '<pre>'; print_r($res); echo '</pre>';

Большинство ajax форм на сайте отправляют данные и принимают ответ со стороны сервера именно в формате JSON

PUT запрос

HTTP-метод PUT используется в REST API для обновления данных, хотя обычно все забивают и пользуются POST-ом.

//Подготовка данных
$data = [
	'user'  => 'Max',
	'age' => 26,
	'position' => 'Marketolog'
];		
 
$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data, '', '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$html = curl_exec($ch);

curl_close($ch);	
 
echo $html;

DELETE запрос

Ещё один метод, который используется в REST API и служит для удаления данных.

$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

curl_exec($ch);
curl_close($ch);

Запрос через proxy сервер

Иногда нужно послать запрос через сторонний шлюз, чтобы не палиться, например во время парсинга сайтов

//Параметры proxy сервера
$proxy = '192.168.155.214';
$proxyPort = '8000';
 
$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_TIMEOUT, 400);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

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

Отправка файлов на удалённый сервер

Для отправки файлов используется метод POST. Старые варианты отправки до php 5.5 рассматривать не будем, т.к. на дворе 2023, везде используется минимум php 7 и уже активно продвигается php 8.1.

Для отправки файл через cURL используется специальная функция curl_file_create() принимающая 3 аргумента: 

  • filename - путь к файлу, который будет загружен
  • mime_type - mime-тип файла.
  • posted_filename - имя файла при отправке методом POST.

$curl_file = curl_file_create(__DIR__ . '/img.png', 'image/png' , 'img.png');

$ch = curl_init('https://site.com');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, ['images' => $curl_file]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

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

Для отправки нескольких файлов сразу, в $curl_files можно передать массив полей.

$curl_files = [
	'images[0]' => curl_file_create(__DIR__ . '/img.png', 'image/png' , 'img.png'),
	'images[1]' => curl_file_create(__DIR__ . '/img2.png', 'image/png' , 'img2.png')
];
Так же файлы можно передать методом PUT:

$file = __DIR__ . '/avatar.jpg';
$fp = fopen($file, 'r');
 
$ch = curl_init('https://site.com');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

curl_exec($ch);
curl_close($ch);

Скачивание файлов

Если в параметр CURLOPT_FILE передать указатель на открыты при помощи fopen() файл, cURL сразу сохранит полученные данные в этот файл.

$file_name = __DIR__ . '/page.html';
$file = @fopen($file_name, 'w');
 
$ch = curl_init('https://site.com');
curl_setopt($ch, CURLOPT_FILE, $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

curl_exec($ch);
curl_close($ch);
 
fclose($file);
Либо используйте проверенный временем file_put_contents()


$ch = curl_init('https://site.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$html = curl_exec($ch);
curl_close($ch);
 
file_put_contents(__DIR__ . '/page.html', $html);

Отправить и получить cookie

Если вам нужно, чтобы cURL сохранил cookie в файл, пропишите его адрес в параметрах CURLOPT_COOKIEFILE и CURLOPT_COOKIEJAR.
$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__ . '/cookie_file.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__ . '/cookie_file.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
 
$html = curl_exec($ch);
curl_close($ch);	
А для передачи значения cookie, используйте параметр CURLOPT_COOKIE.


$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_COOKIE, 'param_name=param_value');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
 
$html = curl_exec($ch);
curl_close($ch)

Мимикрируем под браузер

Иногда пред программистом встаёт задача спарсить какой-то сайт, например справочник товаров партнёра (часто партнёры интернет-магазинов не имеют вменяемых материалов для передачи), но многие сайты защищены от парсинга средствами сервера. Они отличают сеанс реального пользователя от запросов с cURL проверяя такие параметры как UserAgent, Referer и другие. Если их не передать специально, сервер вернёт ошибку 404 или 500 и не позволит вам спарсить страницу. Чтобы нам имитировать браузер при запросах к сайту, необходимо передать набор заголовков присущих браузеру реального посетителя. Например:


$headers = [
	'cache-control: max-age=0',
	'upgrade-insecure-requests: 1',
	'user-agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36',
	'sec-fetch-user: ?1',
	'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
	'x-compress: null',
	'sec-fetch-site: none',
	'sec-fetch-mode: navigate',
	'accept-encoding: deflate, br',
	'accept-language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
];
 
$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__ . '/cookie_file.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__ . '/cookie_file.txt');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, true);

$html = curl_exec($ch);
curl_close($ch);
 
echo $html;

В особых случаях, можно даже написать функцию и собирать массив $headers налету, под каждый запрос. Пусть сайт думает что его посещают разные люди.

HTTP Авторизация средствами cURL

Basic Authorization 

Если на сайте настроена HTTP авторизация, например чере .htpasswd, войти на сайт, можно при помощи параметра CURLOPT_USERPWD.

$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_USERPWD, 'login:password');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$html = curl_exec($ch);
curl_close($ch);
 
echo $html;

OAuth авторизация


$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth TOKEN']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$html = curl_exec($ch);
curl_close($ch);
 
echo $html;

Получить HTTP код ответа сервера

Про коды ответа веб-сервера можно почитать в этой статье.

$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
 
echo $http_code; // Если сайт доступен, выведет код: 200

Если CURL возвращает false

В случае если запрос к ресурсу через cURL вернул false, произошла какая-то ошибка, чтобы узнать что именно случилось нужно воспользоваться следующими фунциями:
  • curl_errno() - возвращает код последней ошибки
  • curl_strerror() -  получить текстовое описание для кода ошибки

$ch = curl_init('https://site.com');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
$res = curl_exec($ch);
 
var_dump($res); //получили false
 
if ($errno = curl_errno($ch)) {
	$message = curl_strerror($errno);
	echo 'cURL error (' . $errno . '): ' . $message; //Выведет код и текстовое описание ошибки
}
					
curl_close($ch);


Библиотеки

Чтобы упросить работу с HTTP запросами, можно воспользоваться готовым решением, библиотекой Guzzle. Она позволяет избежать громоздкого написания кода, быстро и удобно отправлять данные нужным способом (GET, POST и т.п.). Имеет в своём арсенале много удобных методов, позволяющих получать мета-информацию о запросах.


$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.github.com/user', [
    'auth' => ['user', 'pass']
]);
echo $res->getStatusCode();
// "200"
echo $res->getHeader('content-type')[0];
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'
Так же предусмотрена работа с асинхронными запросами

// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
    echo 'I completed! ' . $response->getBody();
});
$promise->wait();
Пользуйтесь готовыми примерами cURL или целыми библиотеками. Удачи!
Полезная статья?
(Голосов: 4, Рейтинг: 3.59)
Вам также могут понравиться
Английский для программистов

Английский для программистов

Почему IT-специалисту необходимо освоить английский язык? Разбираем в статье.

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как правильно подключать стили и скрипты к шаблону 1С Битрикс.

Генерация оглавления статьи

Генерация оглавления статьи

В статье рассмотрен пример функции для генерации оглавления статьи блога или новости


Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке