Документация для разработчиков
Темная тема

PSR-18: HTTP Client

Интерфейс \Psr\Http\Client\ClientInterface содержит всего один метод для отправки HTTP-запроса:

interface ClientInterface
{
	public function sendRequest(RequestInterface $request): ResponseInterface;
}

PSR требует создать и передать объект запроса типа RequestInterface и возвращает объект ответа типа ResponseInterface (описаны в PSR-7). Обработка ошибок реализуется на исключениях. В ядре интерфейсы PSR-7 реализованы в классах:

  • \Bitrix\Main\Web\Uri – URI;
  • \Bitrix\Main\Web\Http\Request – запрос;
  • \Bitrix\Main\Web\Http\Response – ответ;
  • \Bitrix\Main\Web\Http\Stream – тело запроса/ответа;
  • \Bitrix\Main\Web\Http\ClientException – исключение верхнего уровня;
  • \Bitrix\Main\Web\Http\RequestException – ошибка запроса;
  • \Bitrix\Main\Web\Http\NetworkException – сетевая ошибка.

Особенностью PSR-7 является использование потоков для тела запроса и ответа. Ниже пример отправки формы методом POST:

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
use Bitrix\Main\Web\Http\Stream;
//use Bitrix\Main\Web\Http\FormStream;
use Bitrix\Main\Web\Http\ClientException;
	
$http = new HttpClient([
	'compress' => true,
]);
	
$data = [
	"k1" => "v1",
	"k2" => "v2",
];
	
$uri = new Uri('http://vm.vad/test.php');
	
// подготовка тела запроса
$body = new Stream('php://temp', 'r+');
$body->write(http_build_query($data, '', '&'));
	
// ИЛИ более простой способ (main 23.300.0)
// $body = new FormStream($data);
	
$request = new Request(Method::POST, $uri, [], $body);
	
try
{
	$response = $http->sendRequest($request);
	
	var_dump($response->getStatusCode());
	var_dump($response->getHeaders());
	var_dump((string)$response->getBody());
}
catch (ClientException $e)
{
	var_dump($e->getMessage());
}

Рассмотрим более сложный пример, когда нужно передать файл методом POST:

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
use Bitrix\Main\Web\Http\MultipartStream;
use Bitrix\Main\Web\Http\ClientException;
	
$http = new HttpClient([
	'compress' => true,
]);
	
	
$res = fopen("/home/bitrix/www/20190807_120929.jpg", 'r');
	
$data = [
	"k1" => "v1",
	"k2" => "v2",
	"k3" => [
		'resource' => $res,
		'filename' => "pic.jpg",
	],
];
	
$uri = new Uri('http://vm.vad/test.php');
	
$body = new MultipartStream($data);
	
$headers = [
	'User-Agent' => 'bitrix',
	'Content-type' => 'multipart/form-data; boundary=' . $body->getBoundary(),
];
	
$request = new Request(Method::POST, $uri, $headers, $body);
	
fclose($res);
	
try
{
	$response = $http->sendRequest($request);
	
	var_dump($response->getStatusCode());
	var_dump($response->getHeaders());
	var_dump((string)$response->getBody());
}
catch (ClientException $e)
{
	var_dump($e->getMessage());
}

Обратите внимание, что ответ с редиректом будет возвращён как есть, без перехода по заголовку Location. PSR-18 считает, что ответы с кодом 30x ничем не отличаются от всех остальных. Пример обработки редиректа может выглядеть так:

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
use Bitrix\Main\Web\Http\ClientException;
	
$http = new HttpClient([
	'compress' => true,
	'disableSslVerification' => true,
]);
	
$uri = new Uri('http://1с-битрикс.рф/');
	
$request = new Request(Method::GET, $uri);
	
try
{
	do
	{	
		$response = $http->sendRequest($request);
		
		if ($response->hasHeader('Location'))
		{
			$location = $response->getHeader('Location')[0];
			var_dump($location);
			
			$request = $request->withUri(new Uri($location));
		}
	}
	while ($response->hasHeader('Location'));
	
//	var_dump((string)$response->getBody());
}
catch (ClientException $e)
{
	var_dump($e->getMessage());
}
	
/*
Распечатает:
string(37) "https://xn--1--clc2aam4begg.xn--p1ai/"
string(25) "https://www.1c-bitrix.ru/"
*/

Вместо вышеуказанного можно использовать старый способ:

use Bitrix\Main\Web\HttpClient;
	
$http = (new HttpClient())->disableSslVerification();
	
var_dump($http->get('http://1с-битрикс.рф/'));


Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
© «Битрикс», 2001-2024, «1С-Битрикс», 2024
Наверх