JavaScript Editor Javascript validator     Web page editor 


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.

Example 48-1. Download progress bar with HTTP_Request_Listener

 * 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';



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()

    * 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);

            case 'gotHeaders':
                if (isset($data['content-disposition']) &&
                    preg_match('/filename="([^"]+)"/', $data['content-disposition'], $matches)) {

                } else {
                $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;

            case 'tick':
                $this->_size += strlen($data);
                $this->_bar->update(round($this->_size / 1024));
                fwrite($this->_fp, $data);

            case 'gotBody':

                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 = '';

$req =& new HTTP_Request($url);

$download =& new HTTP_Request_DownloadListener();

Events that can be caught

The HTTP_Request class sends these events:

The HTTP_Response class sends these events:

JavaScript Editor Javascript validator     Web page editor