A PSR-7/PSR-17/PSR-18 HTTP message/client implementation.
An API documentation created with phpDocumentor can be found at https://chillerlan.github.io/php-httpinterface/ (WIP).
- PHP 8.1+
ext-curl
- from dependencies:
Installation with composer
composer require chillerlan/php-httpinterface
{
"require": {
"php": "^8.1",
"chillerlan/php-httpinterface": "dev-main#<commit_hash>"
}
}
Note: replace dev-main
with a version constraint, e.g. ^6.0
- see releases for valid versions.
Profit!
The HTTP clients CurlClient
and StreamClient
are invoked with a ResponseFactoryInterface
instance
as the first parameter, followed by optional HTTPOptions
and PSR-3 LoggerInterface
instances.
You can then send a request via the implemented PSR-18 method ClientInterface::sendRequest()
,
using a PSR-7 RequestInterface
and expect a PSR-7 ResponseInterface
.
$options = new HTTPOptions;
$options->ca_info = '/path/to/cacert.pem';
$options->user_agent = 'my cool user agent 1.0';
$options->dns_over_https = 'https://cloudflare-dns.com/dns-query';
$httpClient = new CurlClient($responseFactory, $options, $logger);
$request = $requestFactory->createRequest('GET', 'https://www.example.com?foo=bar');
$httpClient->sendRequest($request);
The CurlMultiClient
client implements asynchronous multi requests ("rolling-curl").
It needs a MultiResponseHandlerInterface
that parses the incoming responses, the callback may return a failed request to the stack:
$handler = new class () implements MultiResponseHandlerInterface{
public function handleResponse(
ResponseInterface $response, // the incoming response
RequestInterface $request, // the corresponding request
int $id, // the request id
array|null $curl_info, // the curl_getinfo() result for this request
):RequestInterface|null{
if($response->getStatusCode() !== 200){
// return the failed request back to the stack
return $request;
}
try{
$body = $response->getBody();
// the response body is empty for some reason, we pretend that's fine and exit
if($body->getSize() === 0){
return null;
}
// parse the response body, store the result etc.
$data = $body->getContents();
// save data to file, database or whatever...
// ...
}
catch(Throwable){
// something went wrong, return the request to the stack for another try
return $request;
}
// everything ok, nothing to return
return null;
}
};
You can then invoke the multi request client - the MultiResponseHandlerInterface
and ResponseFactoryInterface
are mandatory,
HTTPOptions
and LoggerInterface
are optional:
$options = new HTTPOptions;
$options->ca_info = '/path/to/cacert.pem';
$options->user_agent = 'my cool user agent 1.0';
$options->sleep = 750000; // microseconds, see usleep()
$options->window_size = 5;
$options->retries = 1;
$multiClient = new CurlMultiClient($handler, $responseFactory, $options, $logger);
// create and add the requests
foreach(['..', '...', '....'] as $item){
$multiClient->addRequest($factory->createRequest('GET', $endpoint.'/'.$item));
}
// process the queue
$multiClient->process();
The URLExtractor
wraps a PSR-18 ClientInterface
to extract and follow shortened URLs to their original location.
$options = new HTTPOptions;
$options->user_agent = 'my cool user agent 1.0';
$options->ssl_verifypeer = false;
$options->curl_options = [
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_MAXREDIRS => 25,
];
$httpClient = new CurlClient($responseFactory, $options, $logger);
$urlExtractor = new URLExtractor($httpClient, $responseFactory);
$request = $factory->createRequest('GET', 'https://t.co/ZSS6nVOcVp');
$urlExtractor->sendRequest($request); // -> response from the final location
// you can retrieve an array with all followed locations afterwards
$responses = $this->http->getResponses(); // -> ResponseInterface[]
// if you just want the URL of the final location, you can use the extract method:
$url = $this->http->extract('https://t.co/ZSS6nVOcVp'); // -> https://api.guildwars2.com/v2/build
The LoggingClient
wraps a ClientInterface
and outputs the HTTP messages in a readable way through a LoggerInterface
(do NOT use in production!).
$loggingClient = new LoggingClient($httpClient, $logger);
$loggingClient->sendRequest($request); // -> log to output given via logger
The API documentation can be auto generated with phpDocumentor. There is an online version available via the gh-pages branch that is automatically deployed on each push to main.
Locally created docs will appear in the directory .build/phpdocs/
. If you'd like to create local docs, please follow these steps:
- download phpDocumentor v3+ as .phar archive
- run it in the repository root directory:
- on Windows
c:\path\to\php.exe c:\path\to\phpDocumentor.phar --config=phpdoc.xml
- on Linux just
php /path/to/phpDocumentor.phar --config=phpdoc.xml
- on Windows
- open index.html in a browser
- profit!
Use at your own risk!