При интеграции сайта на Битрикс часто возникает необходимость парсинга других сайтов или интеграции с внешними сервисами, а следовательно возникает вопрос о том, как обратиться к стороннему URL. В старом ядре был класс CHTTP для этих целей, но из-за отсутствия документации по нему, обычно искали решение в fopen, file_get_contents, curl и т.п. Эта статья посвящена новым классам для работы с URL и HTTP-запросами в Битрикс D7. Классы собраны в пространстве имён Bitrix\Main\Web. В статье используются следующие сокращения:
use \Bitrix\Main\Application,
\Bitrix\Main\Web\Uri,
\Bitrix\Main\Web\HttpClient;
Судя по документации, класс HttpClient появился в версии 14.0.15, Uri появился в 12.0.7, но большинство методов были реализованы только в 15.5.10.
Bitrix\Main\Web\Uri
Класс Uri содержит методы для работы с адресом страницы. Фактически это надстройка над функциями PHP parse_url и http_build_query.
Конструктор принимает адрес, возьмем для примера адрес текущей страницы с некоторыми дополнениями:
$uri = new Uri("http://username:password@mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/?param1=value#comments");
Ниже перечислены примеры работы с этим адресом:
$uri->getLocator(); // "http://mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/?param1=value"
$uri->getUri(); // "http://mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/?param1=value#comments"
$uri->getHost(); // "mrcappuccino.ru"
$uri->getUser(); // "username"
$uri->getPass(); // "password"
$uri->getPath(); // "/blog/post/work-with-http-bitrix-d7/"
$uri->getPathQuery(); // "/blog/post/work-with-http-bitrix-d7/?param1=value"
$uri->getPort(); // 80
$uri->getQuery(); // "param1=value"
$uri->getScheme(); // "http"
$uri->deleteParams(array("param1"));
$uri->getUri(); // "http://mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/#comments"
$uri->addParams(array("param2" => "value"));
$uri->getUri(); // "http://mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/?param2=value#comments"
Сменив протокол на https, получим:
$uri = new Uri("https://mrcappuccino.ru/blog/post/work-with-http-bitrix-d7/");
$uri->getScheme(); // "https"
$uri->getPort(); // 443
Таким образом, получаем аналог CMain::GetCurPageParam из старого ядра и генератор URI для запросов:
$uri = new Uri("http://api.ru/");
$uri->addParams(array("token" => "89ud98gdfj78w", "data" => "ЙЦУКЕН ГШЩЗХЪ"));
var_dump($uri->getUri()); // string(113) "http://api.ru/?token=89ud98gdfj78w&data=%D0%99%D0%A6%D0%A3%D0%9A%D0%95%D0%9D+%D0%93%D0%A8%D0%A9%D0%97%D0%A5%D0%AA"
Bitrix\Main\Web\HttpClient
Класс HttpClient является реализацией HTTP-клиента в Битрикс D7, конструктор класса принимает необязательный массив опций:
// опции по умолчанию:
$options = array(
"redirect" => true, // true, если нужно выполнять редиректы
"redirectMax" => 5, // Максимальное количество редиректов
"waitResponse" => true, // true - ждать ответа, false - отключаться после запроса
"socketTimeout" => 30, // Таймаут соединения, сек
"streamTimeout" => 60, // Таймаут чтения ответа, сек, 0 - без таймаута
"version" => HttpClient::HTTP_1_0, // версия HTTP (HttpClient::HTTP_1_0 или HttpClient::HTTP_1_1)
"proxyHost" => "", // адрес
"proxyPort" => "", // порт
"proxyUser" => "", // имя
"proxyPassword" => "", // пароль
"compress" => false, // true - принимать gzip (Accept-Encoding: gzip)
"charset" => "", // Кодировка тела для POST и PUT
"disableSslVerification" => false, // true - отключить проверку ssl (с 15.5.9)
);
$httpClient = new HttpClient($options);
Также опции можно установить сеттерами:
/** @param bool $followRedirects, @param int $redirectMax(default null) */
$httpClient->setRedirect($followRedirects, $redirectMax = null);
/** @param bool $waitResponse */
$httpClient->waitResponse($waitResponse);
/** @param int $socketTimeout */
$httpClient->setTimeout($socketTimeout);
/** @param int $streamTimeout */
$httpClient->setStreamTimeout($streamTimeout);
/** @param string $version */
$httpClient->setVersion($version);
/** @param string $proxyHost, @param int $proxyPort(default null), @param string $proxyUser(default null), @param string $proxyPassword(default null) */
$httpClient->setProxy($proxyHost, $proxyPort = null, $proxyUser = null, $proxyPassword = null);
/** @param bool $compress */
$httpClient->setCompress($compress);
/** @param string $charset */
$httpClient->setCharset($charset);
$httpClient->disableSslVerification();
С версии 16.0.14 опции по умолчанию также можно менять в файле настроек в http_client_options.
// ...
'http_client_options' =>
array (
'value' =>
array (
'redirect' => true,
'redirectMax' => 3,
//...
),
'readonly' => false,
),
// ...
Установить заголовки можно методом setHeader, третий аргумент $replace определяет нужно ли заменить заголовок (true, по умолчанию) или добавить еще с этим именем (false):
$name = "User-Agent";
$value = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A";
$httpClient->setHeader($name, $value, true);
Установить cookies для запроса можно методом setCookies, метод принимает массив имя => значение:
$cookies = array(
"name" => "value",
);
$httpClient->setCookies($cookies);
Для установки имени и пароля для basic authorization нужно вызвать метод setAuthorization:
$httpClient->setAuthorization($user, $pass);
Для выполнения запроса используется метод query:
$httpClient->query($method, $url, $entityBody = null);
Аргумент $method - метод запроса: GET, POST и т.д., можно использовать константы класса: HttpClient::HTTP_GET, HttpClient::HTTP_POST, HttpClient::HTTP_PUT, HttpClient::HTTP_HEAD и HttpClient::HTTP_PATCH. В $entityBody передаём тело запроса.
Метод возвращает результат запроса - true или false. Чтобы получить информацию об ответе, можно использовать методы:
$httpClient->getResult(); // текст ответа
$httpClient->getStatus(); // код статуса ответа
$httpClient->getContentType(); // Content-Type ответа
$httpClient->getEffectiveUrl(); // реальный url ответа, т.е. после редиректов
$httpClient->getCookies(); // объект Bitrix\Main\Web\HttpCookies
$httpClient->getHeaders(); // объект Bitrix\Main\Web\HttpHeaders
$httpClient->getError(); // массив ошибок
У объектов Bitrix\Main\Web\HttpCookies и Bitrix\Main\Web\HttpHeaders есть метод toArray() для получения массива cookies и заголовков соответственно.
Вместо query можно использовать короткие вызовы в соответствии с методом запроса:
$httpClient->get($url); // Возвращает тело ответа
$httpClient->post($url, $postData); // Возвращает тело ответа
$httpClient->head($url); // Возвращает объект Bitrix\Main\Web\HttpHeaders
Также класс HttpClient позволяет скачивать файлы методом GET:
$httpClient->download('http://example.ru/file.pdf', Application::getDocumentRoot() . '/upload/example/document.pdf');
Про объект Application можно узнать из статьи Объекты Application и Context.