HTTP_Request_Listener
HTTP_Request_Listener --
attaching listeners to HTTP_Request operations
Introduction to HTTP_Request_Listener
HTTP_Request_Listener is an abstract class that can be
extended to capture events and respond to them as they occur. Included
with HTTP_Request is an example of a console-based progress bar. To implement
this, the HTTP_Request_DownloadListener
class is used, which uses the Console_ProgressBar
package to display a download progress meter.
Example usage of HTTP_Request_Listener
In order to use a listener, it must attach to the specific
HTTP_Request or HTTP_Response object
that you want to monitor. The attach code is shown at the bottom of the
example. As you can see, the event listener is propagated from the HTTP_Request
object to any child HTTP_Response objects, and attaching only need happen
to the first HTTP_Request object.
Download progress bar with HTTP_Request_Listener
<?php /** * An example of Listener usage with HTTP_Request. This downloads and saves * the file displaying the progress bar in the process. * * Note two things: * 1) The file should be run in console, not in browser; * 2) You should turn output buffering OFF for this to work properly. */
require_once 'HTTP/Request.php'; require_once 'HTTP/Request/Listener.php'; require_once 'Console/ProgressBar.php';
PEAR::setErrorHandling(PEAR_ERROR_DIE);
set_time_limit(0);
class HTTP_Request_DownloadListener extends HTTP_Request_Listener { /** * Handle for the target file * @var int */ var $_fp;
/** * Console_ProgressBar intance used to display the indicator * @var object */ var $_bar;
/** * Name of the target file * @var string */ var $_target;
/** * Number of bytes received so far * @var int */ var $_size = 0;
function HTTP_Request_DownloadListener() { $this->HTTP_Request_Listener(); }
/** * Opens the target file * @param string Target file name * @throws PEAR_Error */ function setTarget($target) { $this->_target = $target; $this->_fp = @fopen($target, 'wb'); if (!$this->_fp) { PEAR::raiseError("Cannot open '{$target}'"); } }
function update(&$subject, $event, $data = null) { switch ($event) { case 'sentRequest': $this->_target = basename($subject->_url->path); break;
case 'gotHeaders': if (isset($data['content-disposition']) && preg_match('/filename="([^"]+)"/', $data['content-disposition'], $matches)) {
$this->setTarget(basename($matches[1])); } else { $this->setTarget($this->_target); } $this->_bar =& new Console_ProgressBar( '* ' . $this->_target . ' %fraction% KB [%bar%] %percent%', '=>', '-', 79, (isset($data['content-length'])? round($data['content-length'] / 1024): 100) ); $this->_size = 0; break;
case 'tick': $this->_size += strlen($data); $this->_bar->update(round($this->_size / 1024)); fwrite($this->_fp, $data); break;
case 'gotBody': fclose($this->_fp); break;
default: PEAR::raiseError("Unhandled event '{$event}'"); } // switch } }
// Try using any other package if you like, but choose the bigger ones // to be able to see the progress bar $url = 'http://pear.php.net/get/HTML_QuickForm-stable';
$req =& new HTTP_Request($url);
$download =& new HTTP_Request_DownloadListener(); $req->attach($download); $req->sendRequest(false); ?>
|
Events that can be caught
The HTTP_Request class sends these events:
-
connect - upon server connection, this event is sent
-
sentRequest - after the request was sent, this event is sent
-
disconnect - after server disconnect, this event is sent
The HTTP_Response class sends these events:
-
gotHeaders - this event is sent after receiving response headers
(headers are passed in $data as an associative array)
-
tick - this event is sent on receiving a part of response body
(the part is passed in $data as a string)
-
gzTick - this event is sent on receiving a part of response body
that is gzip-compressed (the part is passed in $data as a string)
-
gotBody - this event is sent on after receiving the
complete response body (the decoded body is passed as a string in $data if it was gzipped)