Artax is a full-featured HTTP/1.1 client as specified in RFC 2616. Its API is designed to simplify
standards-compliant HTTP resource traversal and RESTful web service consumption without obscuring the
underlying HTTP protocol. The code manually implements the HTTP over TCP sockets; as such it has no
dependency on PHP's curl_*
API and requires no non-standard PHP extensions.
HEY! Checkout out the EXAMPLES SECTION to see some of the cool stuff Artax can do. Or, scroll to the bottom of this file to see examples of basic usage.
- Eschews any cURL/libcurl dependency
- Exposes APIs for synchronous, parallel and event-driven request/response
- Retains persistent "keep-alive" connections
- Transparently follows redirects
- Requests and decodes gzipped entity bodies
- Provides access to all raw request/response headers and message data
- Streams request and response entity bodies for hands-on memory management
- Supports all standard and custom request methods
- Trivializes submitting HTTP forms for multipart and form-encoded entities via the
FormBody
API - Provides fully customizable and secure-by-default TLS (https://) support
- Exposes a simple subject/observer API for plugins and extensions
- Offers advanced connection limiting options on a per-host basis
- Provides fully automatic cookie support via the Cookie extension
- Offers built-in progress bar and tracking support via the Progress extension
- Model all code as closely as possible to the protocol outlined in RFC 2616;
- Implement an HTTP/1.1 client built on raw sockets with no libcurl dependency;
- Build all components using SOLID, readable and thoroughly unit-tested code;
$ git clone --recursive https://github.com/rdlowrey/Artax.git
Successful recursive clones will place the Alert dependency in the vendor/
directory. When included in your project the autoload.php
script will register class autoloaders
for both Artax
and Alert
namespaces.
$ php composer.phar require rdlowrey/Artax:0.6.*
- PHP 5.4+
- The Alert library (installed automatically if you
git clone --recursive
) - PHP's
openssl
extension if you need TLS (https://) encryption support - PHP's
zlib
extension if you wish to request/decompress gzipped responses
Artax offers two APIs for your HTTP needs:
-
Serial:
Artax\Client
is fully synchronous. You can requests invidual HTTP resources serially or in parallel, but retrieval function calls are always synchronous. -
Async:
Artax\AsyncClient
is fully asynchronous and runs inside a non-blocking event loop. The asynchronous client allows for full IO and computational parallelization. But with great power comes great responsibility; an understanding of non-blocking IO is needed to effectively write code using this paradigm.
Often we only care about simple GET retrieval. For such cases Artax accepts a basic HTTP URI as the request parameter:
<?php
$client = new Artax\Client;
$response = $client->request('http://www.google.com');
echo "Response status code: ", $response->getStatus(), "\n";
echo "Response reason: ", $response->getReason(), "\n";
echo "Response protocol: ", $response->getProtocol(), "\n";
print_r($response->getAllHeaders());
echo $response->getBody();
For non-trivial requests Artax allows you to construct messages piece-by-piece. This example
sets the request method to POST and assigns an entity body. HTTP veterans will notice that
we don't bother to set a Content-Length
or Host
header. Aerys will automatically add/normalize
missing headers for us so we don't need to worry about it. The only property that MUST be assigned
when sending an Artax\Request
is the absolute http:// or https:// request URI:
<?php
$client = new Artax\Client;
$request = new Artax\Request;
$request->setUri('http://httpbin.org/post');
$request->setProtocol('1.1');
$request->setMethod('POST');
$request->setAllHeaders([
'Content-Type' => 'text/plain; charset=utf-8',
'Cookie' => ['Cookie1=val1', 'Cookie2=val2']
]);
$request->setBody('woot!');
$response = $client->request($request);
In the above example the raw request message sent to the server will look like this:
POST /post HTTP/1.1
Host: httpbin.org
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Cookie: Cookie1=val1
Cookie: Cookie2=val2
woot!
Assume that httpbin.org/post
contains the following HTML form:
<form action="http://httpbin.org/post" enctype="multipart/form-data" method="post">
<P>
What is your name? <input type="text" name="name"><br>
What files are you sending?<br>
<input type="file" name="file1"><br>
<input type="file" name="file2"><br>
<input type="submit" value="Send">
</form>
We can easily submit this form using the Artax\FormBody
API:
<?php
$body = new Artax\FormBody;
$body->addField('name', 'Zoroaster');
$body->addFileField('file1', '/hard/path/to/some/file1');
$body->addFileField('file2', '/hard/path/to/some/file2');
$client = new Artax\Client;
$request = new Artax\Request;
$request->setBody($body);
$request->setUri('http://httpbin.org/post');
$request->setMethod('POST');
$response = $client->request($request);
It's important to note that Artax\FormBody
will stream any file fields you specify as
part of your form submission. This means you can easily upload huge files without issue.
The synchronous Artax\Client::requestMulti
retrieves multiple requests in parallel and alerts
the relevant callbacks each time a request in the batch completes:
<?php
$client = new Artax\Client;
$onResponse = function($requestKey, Artax\Response $response) {
echo 'Response: (', $requestKey, ') ', $response->getStatus(), "\n";
};
$onError = function($requestKey, Exception $error) {
echo 'Error: (', $requestKey, ') ', $error->getMessage(), "\n";
};
$requests = [
'google' => 'http://www.google.com',
'google news' => 'http://news.google.com',
'bing' => 'http://www.bing.com',
'yahoo' => 'http://www.yahoo.com',
'php' => 'http://www.php.net'
];
$client->requestMulti($requests, $onResponse, $onError);
Note that though the individual requests in the $requests
batch are retrieved in parallel the
Client::requestMulti
call itself will block until all of the requests complete (or error out).
Check out more examples demonstrating features such as cookies, progress bars, TLS support, asynchronous requests, etc ...
Children of the 1980s are likely familiar with The NeverEnding Story and may remember the scene where Atreyu's faithful steed, Artax, died in the Swamp of Sadness. The name is an homage.