Observers are classes that can be attached to an instance of HTTP_Request2 and notified of request's progress. Possible uses:
HTTP_Request2 implements SplSubject
interface, so Observers should implement SplObserver. When
Observer is notified of an event, it should use HTTP_Request2::getLastEvent() to access event details. That method returns an
associative array with 'name'
and 'data'
keys. Possible
event names are
'connect'
'data'
is the destination (string).
'disconnect'
'sentHeaders'
'data'
is the headers sent (string).
'sentBodyPart'
'data'
is the length of that part
(integer).
'sentBody'
(since release 2.0.0beta1)'data'
is the
length of request body (integer).'receivedHeaders'
'data'
is
HTTP_Request2_Response object containing these headers.
'receivedBodyPart'
'data'
is the received part
(string).
'receivedEncodedBodyPart'
'receivedBodyPart'
, but 'data'
is still encoded by
relevant Content-Encoding
.
'receivedBody'
As the events are actually sent by request Adapters, you can receive fewer or different events if you switch to another Adapter. Curl Adapter does not notify of
'connect'
,'disconnect'
and'receivedEncodedBodyPart'
events (it always uses'receivedBodyPart'
as cURL extension takes care of decoding). Mock Adapter does not send any notifications at all.
The following example shows how an Observer can be used to save response body to disk without storing it in memory. Note that only events relevant to that task are handled in its update() method, the others can be safely ignored.
The package contains another Observer implementation: HTTP_Request2_Observer_Log class that allows logging request progress to a file or an instance of Log.
Saving response body to disk
<?php
class HTTP_Request2_Observer_Download implements SplObserver
{
protected $dir;
protected $fp;
public function __construct($dir)
{
if (!is_dir($dir)) {
throw new Exception("'{$dir}' is not a directory");
}
$this->dir = $dir;
}
public function update(SplSubject $subject)
{
$event = $subject->getLastEvent();
switch ($event['name']) {
case 'receivedHeaders':
if (($disposition = $event['data']->getHeader('content-disposition'))
&& 0 == strpos($disposition, 'attachment')
&& preg_match('/filename="([^"]+)"/', $disposition, $m)
) {
$filename = basename($m[1]);
} else {
$filename = basename($subject->getUrl()->getPath());
}
$target = $this->dir . DIRECTORY_SEPARATOR . $filename;
if (!($this->fp = @fopen($target, 'wb'))) {
throw new Exception("Cannot open target file '{$target}'");
}
break;
case 'receivedBodyPart':
case 'receivedEncodedBodyPart':
fwrite($this->fp, $event['data']);
break;
case 'receivedBody':
fclose($this->fp);
}
}
}
$request = new HTTP_Request2(
'http://pear.php.net/distributions/manual/pear_manual_en.tar.bz2',
HTTP_Request2::METHOD_GET, array('store_body' => false)
);
$request->attach(new HTTP_Request2_Observer_Download('.'));
// This won't output anything since body isn't stored in the response
echo $request->send()->getBody();
?>