HTTP requests to external sources¶
The PHP library "Guzzle" is available in TYPO3 as a feature-rich solution for creating HTTP requests based on the PSR-7 interfaces.
Guzzle automatically detects the underlying adapters available on the system, such as cURL or stream wrappers, and chooses the best solution for the system.
A TYPO3-specific PHP class named \TYPO3\
is
present as a simplified wrapper for accessing Guzzle clients.
All options available under $GLOBALS
are
automatically applied to the Guzzle clients when using the Request
class. The options are a subset of the available options from Guzzle, but can be
extended.
Although Guzzle can handle Promises/A+ and asynchronous requests, it currently
serves as a drop-in replacement for the previous mixed options and
implementations within General
and a PSR-7-based API for
HTTP requests.
The TYPO3-specific wrapper General
uses Guzzle for
remote files, eliminating the need to directly configure settings based on
specific implementations such as stream wrappers or cURL.
Basic usage¶
The Request
class can be used like this (PHP 8.1-compatible code):
<?php
declare(strict_types=1);
namespace T3docs\Examples\Http;
use TYPO3\CMS\Core\Http\RequestFactory;
final class MeowInformationRequester
{
private const API_URL = 'https://catfact.ninja/fact';
// We need the RequestFactory for creating and sending a request,
// so we inject it into the class using constructor injection.
public function __construct(
private readonly RequestFactory $requestFactory,
) {
}
public function request(): string
{
// Additional headers for this specific request
// See: https://docs.guzzlephp.org/en/stable/request-options.html
$additionalOptions = [
'headers' => ['Cache-Control' => 'no-cache'],
'allow_redirects' => false,
];
// Get a PSR-7-compliant response object
$response = $this->requestFactory->request(
self::API_URL,
'GET',
$additionalOptions
);
if ($response->getStatusCode() !== 200) {
throw new \RuntimeException(
'Returned status code is ' . $response->getStatusCode()
);
}
if ($response->getHeaderLine('Content-Type') !== 'application/json') {
throw new \RuntimeException(
'The request did not return JSON data'
);
}
// Get the content as a string on a successful request
return json_decode($response->getBody()->getContents(), true)['fact']
?? throw new \RuntimeException('No information available');
}
}
A POST request can be achieved with:
$additionalOptions = [
'body' => 'Your raw post data',
// OR form data:
'form_params' => [
'first_name' => 'Jane',
'last_name' => 'Doe',
]
];
$response = $this->requestFactory->request($url, 'POST', $additionalOptions);
Extension authors are advised to use the Request
class instead of
using the Guzzle API directly in order to ensure a clear upgrade path when
updates to the underlying API need to be done.
Custom middleware handlers¶
Guzzle accepts a stack of custom middleware handlers which can be configured
in $GLOBALS
as an array. If a
custom configuration is specified, the default handler stack will be extended
and not overwritten.
// Add custom middlewares to default Guzzle handler stack
$GLOBALS['TYPO3_CONF_VARS']['HTTP']['handler'][] =
(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\MyVendor\MyExtension\Middleware\Guzzle\CustomMiddleware::class
))->handler();
$GLOBALS['TYPO3_CONF_VARS']['HTTP']['handler'][] =
(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\MyVendor\MyExtension\Middleware\Guzzle\SecondCustomMiddleware::class
))->handler();
HTTP Utility Methods¶
TYPO3 provides a small set of helper methods related to HTTP Requests in the class Http
:
HttpUtility::redirect¶
Deprecated since version 11.3
This method is deprecated and will be removed with TYPO3 v12.0. Create a direct response using the ResponseFactory instead.
Migration¶
Most of the time, a proper PSR-7 response can be returned to the call stack
(request handler). Unfortunately there might still be some places within the
call stack where it is not possible to return a PSR-7 response directly. In such
a case a \TYPO3\
could be thrown.
This is automatically caught by a PSR-15 middleware and the given PSR-7 response
is then returned directly.
// Before
HttpUtility::redirect('https://example.org/', HttpUtility::HTTP_STATUS_303);
// After
// use Psr\Http\Message\ResponseFactoryInterface
// use TYPO3\CMS\Core\Http\PropagateResponseException
// Inject PSR-17 ResponseFactoryInterface
public function __construct(ResponseFactoryInterface $responseFactory)
{
$this->responseFactory = $responseFactory
}
// Create redirect response
$response = $this->responseFactory
->createResponse(303)
->withAddedHeader('location', 'https://example.org/')
// Return response directly
return $response;
// Or throw PropagateResponseException
new PropagateResponseException($response);
Note
Throwing exceptions for returning an immediate PSR-7 response is only
considered as an intermediate solution until it is possible to return PSR-7
responses at any relevant place. Therefore, the exception is marked as
@internal
and will most likely vanish in the future.
HttpUtility::setResponseCode¶
Deprecated since version 11.3
This method is deprecated and will be removed with TYPO3 v12.0. Create a direct response using the ResponseFactory instead. See also Migration.
HttpUtility::setResponseCodeAndExit¶
Deprecated since version 11.3
This method is deprecated and will be removed with TYPO3 v12.0. Create a direct response using the ResponseFactory instead. See also Migration.
HttpUtility::buildUrl¶
Creates a URL string from an array containing the URL parts, such as those
output by parse_
.
HttpUtility::buildQueryString¶
The build
method is an enhancement to the PHP function
http_
. It implodes multidimensional parameter arrays and
properly encodes parameter names as well as values into a valid query string
with an optional prepend of ?
or &
.
If the query is not empty, ?
or &
are prepended in the correct sequence.
Empty parameters are skipped.