Make A Request

HttpClient is a simple class to make restful request.

use Windwalker\Http\HttpClient;

$http = new HttpClient;

$response = $http->get('');

// This is PSR7 ResponseInterface
(string) $response->getBody();

Other Methods

$http = new HttpClient;

// The post data can be query string or array
$response = $http->post('', array('post_data' => 'data'));
$response = $http->put('', array('post_data' => 'data'));
$response = $http->patch('', array('post_data' => 'data'));
$response = $http->delete('', array('post_data' => 'data'));

$response = $http->head('');
$response = $http->trace('');
$response = $http->options('');

// With headers
$response = $http->get('', null, array('X-Foo' => 'Bar'));

// Use request()
$response = $http->request('POST', '', 'this=is&post=data');

Use Psr RequestInterface to Make Request

Psr7 Request is a immutable object, you have to get the return object every operation.

use Windwalker\Http\Request;

$request = new Request;

// Note: You have to get the return value.
// Every change will return new object.
$request = $request->withRequestTarget('')
    ->withAddedHeader('Authorization', 'Bearer ' . $token)
    ->withAddedHeader('Content-Type', 'application/text');

// OR
$request = new Request(
        'Authorization' => 'Bearer ' . $token,
        'Content-Type'  => 'application/json',

// This is a POST request so we write post data to body

$http = new HttpClient;

// Send request
$response = $http->send($request);

Use Uri and Json output.

use Windwalker\Http\Request;
use Windwalker\Uri\PsrUri;

$request = (new Request)
    ->withUri(new PsrUri(''))
    ->withAddedHeader('Authorization', 'Bearer ' . $token)
    ->withAddedHeader('Content-Type', 'application/json') // Use JSON

    // Note: Request will ignore path and query in Uri
    // So we have to set RequestTarget here

// If you want to set a non-origin-form request target, set the
// request-target explicitly:
$request = $request->withRequestTarget((string) $uri);       // absolute-form
$request = $request->withRequestTarget($uri->getAuthority(); // authority-form
$request = $request->withRequestTarget('*');                 // asterisk-form

// This is JSON request so we encode data here
$response = $http->send($request);

$response->getStatusCode(); // 200 is OK

Custom Transports and Options

Now support Curl and Steam 2 transports.

use Windwalker\Http\Transport\CurlTransport;

$options = array(
    'certpath' => '/custom/cert.pem'

$transport = new CurlTransport($options);

// Set transport when client new
$http = new HttpClient(array(), $transport);

Set custom CURL options:

$options = array(
    'options' => array(
        CURLOPT_SSL_VERIFYHOST => false,

$httpOptions = array(
    'headers' => array(
        'X-Foo' => 'Bar'

$http = new HttpClient($httpOptions, new CurlTransport($options));

Download Remote File

$http = new HttpClient;

$dest = '/path/to/local/';

$response = $http->download('', $dest);

if ($response->getStatusCode() != 200)
    // Error

Response Interface

Response object holds a Stream object to store returned string.

// The return value is: 'FOO BAR'
$body = $response->getBody();

// Simply to string
(string) $body; // FOO BAR

$body->getContents(); // O BAR

$body->read(5); // FOO B

$body->getSize(); // 7

Async Request

Use AsyncHttpClient to send multiple async requests.

use Windwalker\Http\AsyncHttpClient;

$http = new \Windwalker\Http\AsyncHttpClient;

// Add request commands to pool.

// Do request and get responses array
$responses = $http->resolve();

foreach ($responses as $response)
    echo $response->getBody()->__toString();

// Get errors, will be an array contains RuntimeExceptions
$errors = $http->getErrors();

Use callback:

$http->resolve(function ($responses, $errors, $http)
    foreach ($responses as $response)
        echo $response->getBody()->__toString();


Uri is a simple Uri object to modify URL but not Psr UriInterface.

The methods provided in the Uri class allow you to manipulate all aspects of a uri. For example, suppose you wanted to set a new uri, add in a port, and then also post a username and password to authenticate a .htaccess security file. You could use the following syntax:

// new uri object
$uri = new Windwalker\Uri\Uri;


echo $uri->__toString();

This will output:


If you wanted to add a specific filepath after the host you could use the setPath() method:

// set path

Which will output


Adding a URL query:

// url query




PsrUri is a Uri object implemented the Psr UriInterface.

This object is also immutable, so we must get return value as new object every change.

$uri = (new PsrUri(''))
    ->withUserInfo('user', 'pass')

(string) $uri; //


Stream is a powerful stream wrapper.

Read write data to memory:

$stream = new Stream('php://memory', 'wb+');

$stream->write('Foo Bar');

$stream->rewind(); // Back to begin

// Now we take something we wrote into memory

$stream->__toString(); // get: Foo Bar

// OR

$stream->getContents(); // get: Foo Bar

Read data from php://input

$stream = new PhpInputSteam;

$data = $stream->__toString(); // foo=bar

$query = \Windwalker\Uri\UriHelper::parseQuery($data); // array('foo' => 'bar')

Read file:

$stream = new Stream('/path/to/file.txt', 'r+');

$stream->__toString(); // Read

$steam->write('new string'); // Write

Quick copy stream.

// Remote source
$src = new Stream('http://example/test.txt');

// Local store
$dest = new Stream('/path/to/local/test.txt');

// Do copy
\Windwalker\Http\Helper\StreamHelper::copy($src, $dest);

// Get Data
$data = $dest->getContents();


Windwalker Http provides a set of formatted Responses to return data with different formats.

$response = new \Windwalker\Http\Response\HtmlResponse('<html> ... </html>');
$response = new \Windwalker\Http\Response\JsonResponse(array('foo' => 'bar'), 200, $headers);
$response = new \Windwalker\Http\Response\XmlResponse(new \SimpleXMLElement('<root />'), 200, $headers);
$response = new \Windwalker\Http\Response\RedirectResponse($url, 301);
$response = new \Windwalker\Http\Response\AttachmentResponse('file');

See: Psr7 StreamInterface / API

If you found a typo or error, please help us improve this document.