Саратовский железнодорожный мост, логотип джумла и текст HttpFactory

Написал перевод-компиляцию 3-х статей на хабре, которая будет полезна разработчикам при интеграции Joomla со сторонними сервисами по API. Дублирую текст себе.

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

С использованием Joomla довольно легко настроить cURL и все необходимые резервные варианты подключений в одной строчке кода.

use Joomla\CMS\Http\HttpFactory;
$http = HttpFactory::getHttp(null, ['curl', 'stream']);

Этот код вызывает драйвер Joomla Http, позволяющий делать исходящие запросы на внешние URL. Этот драйвер использует драйверы транспорта в указанном порядке, то есть в данном случае в начале cURL (если доступен), а затем stream.

В Joomla 3 "из коробки" доступны 3 драйвера транспорта:

  • cURL
  • socket
  • stream

HttpFactory в Joomla 4

В Joomla 4+ изменены типы методов. Теперь вызов осуществляется не статическим методом (без двоеточия). Например, следующим образом:

$http = (new \Joomla\Http\HttpFactory)->getHttp([], ['curl', 'stream']);

Также обратите внимание, что первый параметр теперь не может быть null, это должен быть массив.

Создание вызова

HttpFactory в Joomla 3 поддерживает следующие типы HTTP-запросов:

  • delete
  • get
  • head
  • options
  • patch
  • post
  • put
  • trace

Все эти методы, кроме GET, используют одинаковые аргументы:

  1. URL - url вызова, end-point.
  2. Data - массив данных, отправляемых в запросе.
  3. Headers - заголовки http-запроса. Могут использоваться, например, для авторизации.
  4. Timeout - установка специфичного таймаута для запроса.

В методе GET отсутствует параметр $data. Используются только $url, $headers, $timeout.

Пример POST-запроса

$answer = $http->post($url);

POST-запрос с данными 

$answer = $http->post($url, ['foo' => 'bar']);

Добавление опций запроса

HttpFactory может добавлять опции настроек для драйвера транспорта. Для этого нужно создать массив, где ключ - это опция, а значение - значение опции соответственно. Ниже примеры опций для cURL. Полный список в документации PHP.

$curlOptions = array();
$curlOptions[CURLOPT_SSL_VERIFYHOST] = false;

Далее добавляем массив с опциями с помощью метода setOption().

$http->setOption('transport.curl', $curlOptions);

Ещё одним вариантом указания опций запроса может быть создание экземпляра класса сразу с заранее заданными опциями. При этом возможно (и это удобно) использовать класс Joomla\Registry\Registry для операций с массивами и объектами.


<?php
use Joomla\Registry\Registry;
use Joomla\CMS\Http\HttpFactory;

$options = new Registry();
$options->set('userAgent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0');

$options->set(
	'transport.curl',
	[
		CURLOPT_SSL_VERIFYPEER => false,
		CURLOPT_SSL_VERIFYHOST => false,
		CURLOPT_PROXY          => null,
		CURLOPT_PROXYUSERPWD   => null,
	]
);
$http = (new HttpFactory)->getHttp($options, ['curl', 'stream']);

Токены аутентификации в заголовках Http-запроса Joomla

Joomla может взаимодействовать с внешним миром получая или отправляя данные. Многие сервисы требуют наличие заголовков запроса с токенами аутентификации. Подробнее в Обзоре способов и протоколов аутентификации в веб-приложениях.

Добавить нужные заголовки весьма просто. Создаем массив с нужными заголовками, а затем указываем его при создании Http-запроса.

if (!empty($access_token) && !empty($user_key)) {
    $headers = [
        'Authorization'        => 'AccessToken ' . $access_token,
        'Content-Type'         => 'application/json',
        'charset'              => 'UTF-8',
        'X-User-Authorization' => 'Basic ' . $user_key,
    ];

    if (!is_null($data)) {
        $headers['Content-Length'] = strlen($data);
    }
    $http->post($url, $data, $headers);
}

Далее уже оборачиваем запрос в try-catch и обрабатываем ошибки.

Обработка ответа

Ответом всегда является объект класса HttpResponse. Он имеет 3 свойства:

  • code - код ответа сервера (200, 400, 301 и т.д.)
  • headers - заголовки ответа сервера
  • body - собственно тело ответа сервера

Обработка HTTP ответа в Joomla 6+

Upd: 14.11.2025г. Описанный выше подход в обработке результатов запроса работал в Joomla 3 - Joomla 5. Однако, Joomla, начиная с Joomla 4 во многом переходит на стандарты PSR. В частности для работы с HTTP-ответами - на PSR-7. Также хорошая статья на Хабре о PSR-7: PSR-7 в примерах.

Прямое обращение к свойствам code, headers, body объявлено устаревшим в Joomla 6.0.0 и обещают удалить в Joomla 7.0.0.

Вместо этого нужно работать с HTTP-ответом по стандартам PSR-7. Например, наш запрос:

use Joomla\Http\HttpFactory;

$http = (new HttpFactory)->getHttp($options, ['curl', 'stream']);
$response = $http->get('https://any-url.ru/api/any/endpoint');
Свойство ответаСтарый вариант, Joomla 3 - Joomla 5Новый, Joomla 6+
Код ответа $response->code $response->getStatusCode()
Заголовки ответа $response->headers $response->getHeaders()
Тело ответа $response->body (string)$response->getBody()->getContents()

В тело ответа теперь приходит не строка, а поток - объект класса Laminas\Diactoros\Stream. Поэтому его нужно привести к строке (если это json, к примеру): (string)$response->getBody()->getContents(). Чаще всего в коде Joomla встречается именно такой вариант. Однако, есть и вариант с перемещением указателя чтения на начало потока:

// Получили ответ в виде потока
$stream = $response->getBody();
// "перемотали" на начало
$stream->rewind();
// Получили строковый ответ
$json = $stream->getContents();

В итоге результат одинаковый. 

Upd. 24.11.2025г. Ещё один пример кода из Joomla-чатов, для использования в Joomla 5 / Joomla 6.

<?php
use Joomla\Http\HttpFactory;
use Joomla\Registry\Registry;

/**
   * Method to set post request.
   *
   * @param   string  $url      Request url.
   * @param   array   $data     Request data.
   * @param   array   $headers  Request headers.
   *
   * @throws \Exception
   *
   * @return Registry Request response Registry object.
   *
   * @since __DEPLOY_VERSION__
   */
  protected function sendPostRequest(string $url, array $data, array $headers = []): Registry
  {
    if (!isset($headers['Content-Type']))
    {
      $headers['Content-Type'] = 'application/json';
    }

    // Send request
    $http = (new HttpFactory)->getHttp();
    $http->setOption('transport.curl', [
      CURLOPT_SSL_VERIFYHOST => 0,
      CURLOPT_SSL_VERIFYPEER => 0
    ]);

    $data = json_encode($data, JSON_UNESCAPED_UNICODE);

    $response = $http->post($url, $data, $headers);
    $code     = $response->getStatusCode();

    $stream = $response->getBody();
    $stream->rewind();
    $contents = $stream->getContents();
    $registry = (!empty($contents) && str_starts_with($contents, '{')) ? new Registry($contents) : false;

    if (!$registry || (int) $registry->get('ErrorCode') !== 0)
    {
      $message = ($registry) ? $registry->get('Message')
        : $code . ': ' . $response->getReasonPhrase();
      $code    = ($registry) ? $registry->get('ErrorCode') : $code;

      throw new \Exception($message, $code);
    }

    return $registry;
  }

Заключение

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

Список источников:

Толкачев Сергей Юрьевич
Толкачев Сергей Юрьевич

Joomla-разработчик. Контрибьютер ядра Joomla. Один из ведущих Telegram-канала русскоязычного Joomla-сообщества JoomlaFeed, один из модераторов чата русскоязычного Joomla-сообщества. Мои расширения в официальном маркетплейсе расширений Joomla - Joomla Extensions Directory. Имею публикации в официальном журнале международного Joomla-сообщества - Joomla Community Magazine.

Муж. Отец 3 детей.

Россия, Саратов.

Расширения Joomla WebTolk

98 Всего расширений
12 Категорий
506 Выпущено версий
588427 Всего скачиваний
Корзина
Корзина пуста