# Client Handlers

Client handlers accept a request array and return a future response array that can be used synchronously as an array or asynchronously using a promise.

## Built-In Handlers

RingPHP comes with three built-in client handlers.

### Stream Handler

The `GuzzleHttp\Ring\Client\StreamHandler` uses PHP’s http stream wrapper to send requests.

Note

This handler cannot send requests concurrently.

You can provide an associative array of custom stream context options to the StreamHandler using the `stream_context` key of the `client` request option.

    use GuzzleHttp\Ring\Client\StreamHandler;

    $response = $handler([
        'http_method' => 'GET',
        'uri' => '/',
        'headers' => ['host' => ['httpbin.org']],
        'client' => [
            'stream_context' => [
                'http' => [
                    'request_fulluri' => true,
                    'method' => 'HEAD'
                ],
                'socket' => [
                    'bindto' => '127.0.0.1:0'
                ],
                'ssl' => [
                    'verify_peer' => false
                ]
            ]
        ]
    ]);

    // Even though it's already completed, you can still use a promise
    $response->then(function ($response) {
        echo $response['status']; // 200
    });

    // Or access the response using the future interface
    echo $response['status']; // 200

### cURL Handler

The `GuzzleHttp\Ring\Client\CurlHandler` can be used with PHP 5.5+ to send requests using cURL easy handles. This handler is great for sending requests one at a time because the execute and select loop is implemented in C code which executes faster and consumes less memory than using PHP’s `curl_multi_*` interface.

Note

This handler cannot send requests concurrently.

When using the CurlHandler, custom curl options can be specified as an associative array of cURL option constants mapping to values in the `client` option of a requst using the curl key.

    use GuzzleHttp\Ring\Client\CurlHandler;

    $handler = new CurlHandler();

    $request = [
        'http_method' => 'GET',
        'headers'     => ['host' => [Server::$host]],
        'client'      => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]]
    ];

    $response = $handler($request);

    // The response can be used directly as an array.
    echo $response['status']; // 200

    // Or, it can be used as a promise (that has already fulfilled).
    $response->then(function ($response) {
        echo $response['status']; // 200
    });

### cURL Multi Handler

The `GuzzleHttp\Ring\Client\CurlMultiHandler` transfers requests using cURL’s multi API. The `CurlMultiHandler` is great for sending requests concurrently.

    use GuzzleHttp\Ring\Client\CurlMultiHandler;

    $handler = new CurlMultiHandler();

    $request = [
        'http_method' => 'GET',
        'headers'     => ['host' => [Server::$host]]
    ];

    // this call returns a future array immediately.
    $response = $handler($request);

    // Ideally, you should use the promise API to not block.
    $response
        ->then(function ($response) {
            // Got the response at some point in the future
            echo $response['status']; // 200
            // Don't break the chain
            return $response;
        })->then(function ($response) {
            // ...
        });

    // If you really need to block, then you can use the response as an
    // associative array. This will block until it has completed.
    echo $response['status']; // 200

Just like the `CurlHandler`, the `CurlMultiHandler` accepts custom curl option in the `curl` key of the `client` request option.

### Mock Handler

The `GuzzleHttp\Ring\Client\MockHandler` is used to return mock responses. When constructed, the handler can be configured to return the same response array over and over, a future response, or a the evaluation of a callback function.

    use GuzzleHttp\Ring\Client\MockHandler;

    // Return a canned response.
    $mock = new MockHandler(['status' => 200]);
    $response = $mock([]);
    assert(200 == $response['status']);
    assert([] == $response['headers']);

## Implementing Handlers

Client handlers are just PHP callables (functions or classes that have the `__invoke` magic method). The callable accepts a request array and MUST return an instance of `GuzzleHttp\Ring\Future\FutureArrayInterface` so that the response can be used by both blocking and non-blocking consumers.

Handlers need to follow a few simple rules:

1. Do not throw exceptions. If an error is encountered, return an array that contains the `error` key that maps to an `\Exception` value.
2. If the request has a `delay` client option, then the handler should only send the request after the specified delay time in seconds. Blocking handlers may find it convenient to just let the `GuzzleHttp\Ring\Core::doSleep($request)` function handle this for them.
3. Always return an instance of `GuzzleHttp\Ring\Future\FutureArrayInterface`.
4. Complete any outstanding requests when the handler is destructed.