SkillAgentSearch skills...

Http

Event-driven, streaming HTTP client and server implementation for ReactPHP.

Install / Use

/learn @reactphp/Http

README

HTTP

CI status installs on Packagist

Event-driven, streaming HTTP client and server implementation for ReactPHP.

Development version: This branch contains the code for the upcoming v3 release. For the code of the current stable v1 release, check out the 1.x branch.

The upcoming v3 release will be the way forward for this package. However, we will still actively support v1 for those not yet on the latest version. See also installation instructions for more details.

This HTTP library provides re-usable implementations for an HTTP client and server based on ReactPHP's Socket and EventLoop components. Its client component allows you to send any number of async HTTP/HTTPS requests concurrently. Its server component allows you to build plaintext HTTP and secure HTTPS servers that accept incoming HTTP requests from HTTP clients (such as web browsers). This library provides async, streaming means for all of this, so you can handle multiple concurrent HTTP requests without blocking.

Table of contents

Quickstart example

Once installed, you can use the following code to access an HTTP web server and send some simple HTTP GET requests:

<?php

require __DIR__ . '/vendor/autoload.php';

$client = new React\Http\Browser();

$client->get('http://www.google.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
    var_dump($response->getHeaders(), (string)$response->getBody());
}, function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

This is an HTTP server which responds with Hello World! to every request.

<?php

require __DIR__ . '/vendor/autoload.php';

$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
    return React\Http\Message\Response::plaintext(
        "Hello World!\n"
    );
});

$socket = new React\Socket\SocketServer('127.0.0.1:8080');
$http->listen($socket);

See also the examples.

Client Usage

Request methods

Most importantly, this project provides a Browser object that offers several methods that resemble the HTTP protocol methods:

$browser->get($url, array $headers = []);
$browser->head($url, array $headers = []);
$browser->post($url, array $headers = [], string|ReadableStreamInterface $body = '');
$browser->delete($url, array $headers = [], string|ReadableStreamInterface $body = '');
$browser->put($url, array $headers = [], string|ReadableStreamInterface $body = '');
$browser->patch($url, array $headers = [], string|ReadableStreamInterface $body = '');

Each of these methods requires a $url and some optional parameters to send an HTTP request. Each of these method names matches the respective HTTP request method, for example the get() method sends an HTTP GET request.

You can optionally pass an associative array of additional $headers that will be sent with this HTTP request. Additionally, each method will automatically add a matching Content-Length request header if an outgoing request body is given and its size is known and non-empty. For an empty request body, if will only include a Content-Length: 0 request header if the request method usually expects a request body (only applies to POST, PUT and PATCH HTTP request methods).

If you're using a streaming request body, it will default to using Transfer-Encoding: chunked unless you explicitly pass in a matching Content-Length request header. See also streaming request for more details.

By default, all of the above methods default to sending requests using the HTTP/1.1 protocol version. If you want to explicitly use the legacy HTTP/1.0 protocol version, you can use the withProtocolVersion() method. If you want to use any other or even custom HTTP request method, you can use the request() method.

Each of the above methods supports async operation and either fulfills with a PSR-7 ResponseInterface or rejects with an Exception. Please see the following chapter about promises for more details.

Promises

Sending requests is async (non-blocking), so you can actually send multiple requests in parallel. The Browser will respond to each request with a PSR-7 ResponseInterface message, the order is not guaranteed. Sending requests uses a Promise-based interface that makes it easy to react to when an HTTP request is completed (i.e. either successfully fulfilled or rejected with an error):

$browser->get($url)->then(
    function (Psr\Http\Message\ResponseInterface $response) {
        var_dump('Response received', $response);
    },
    function (Exception $e) {
        echo 'Error: ' . $e->getMessage() . PHP_EOL;
    }
);

If this looks strange to you, you can also use the more traditional blocking API.

Keep in mind that resolving the Promise with the full response message means the whole response body has to be kept in memory. This is easy to get started and works reasonably well for smaller responses (such as common HTML pages or RESTful or JSON API requests).

You may also want to look into the streaming API:

  • If you're dealing with lots of concurrent requests (100+) or
  • If you want to process individual data chunks as they happen (without having to wait for the full response body) or
  • If you're expecting a big response body size (1 MiB or more, for example when downloading binary files) or
  • If you're unsure about the response body size (better be safe than sorry when accessing arbitrary remote HTTP endpoints and the response body size is unknown in advance).

Cancellation

The returned Promise is implemented in such a way that it can be cancelled when it is still pending. Cancelling a pending promise will reject its value with an Exception and clean up any underlying resources.

$promise = $browser->get($url);

Loop::addTimer(2.0, function () use ($promise) {
    $promise->cancel();
});

Timeouts

This library uses a very efficient HTTP implementation, so most HTTP requests should usually be completed in mere milliseconds. However, when sending HTTP requests over an unreliable network (the internet), there are a number of things that can go wrong and may cause the request to fail after a time. As such, this library respects PHP's default_socket_timeout settin

View on GitHub
GitHub Stars781
CategoryDevelopment
Updated1mo ago
Forks167

Languages

PHP

Security Score

100/100

Audited on Feb 11, 2026

No findings