📄 download.php.svn-base
字号:
<?php/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: *//** * HTTP::Download * * PHP versions 4 and 5 * * @category HTTP * @package HTTP_Download * @author Michael Wallner <mike@php.net> * @copyright 2003-2005 Michael Wallner * @license BSD, revised * @version CVS: $Id$ * @link http://pear.php.net/package/HTTP_Download */// {{{ includes/** * Requires PEAR */require_once 'PEAR.php';/** * Requires HTTP_Header */require_once 'HTTP/Header.php';// }}}// {{{ constants/**#@+ Use with HTTP_Download::setContentDisposition() **//** * Send data as attachment */define('HTTP_DOWNLOAD_ATTACHMENT', 'attachment');/** * Send data inline */define('HTTP_DOWNLOAD_INLINE', 'inline');/**#@-**//**#@+ Use with HTTP_Download::sendArchive() **//** * Send as uncompressed tar archive */define('HTTP_DOWNLOAD_TAR', 'TAR');/** * Send as gzipped tar archive */define('HTTP_DOWNLOAD_TGZ', 'TGZ');/** * Send as bzip2 compressed tar archive */define('HTTP_DOWNLOAD_BZ2', 'BZ2');/** * Send as zip archive */define('HTTP_DOWNLOAD_ZIP', 'ZIP');/**#@-**//**#@+ * Error constants */define('HTTP_DOWNLOAD_E_HEADERS_SENT', -1);define('HTTP_DOWNLOAD_E_NO_EXT_ZLIB', -2);define('HTTP_DOWNLOAD_E_NO_EXT_MMAGIC', -3);define('HTTP_DOWNLOAD_E_INVALID_FILE', -4);define('HTTP_DOWNLOAD_E_INVALID_PARAM', -5);define('HTTP_DOWNLOAD_E_INVALID_RESOURCE', -6);define('HTTP_DOWNLOAD_E_INVALID_REQUEST', -7);define('HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE', -8);define('HTTP_DOWNLOAD_E_INVALID_ARCHIVE_TYPE', -9);/**#@-**/// }}}/** * Send HTTP Downloads/Responses. * * With this package you can handle (hidden) downloads. * It supports partial downloads, resuming and sending * raw data ie. from database BLOBs. * * <i>ATTENTION:</i> * You shouldn't use this package together with ob_gzhandler or * zlib.output_compression enabled in your php.ini, especially * if you want to send already gzipped data! * * @access public * @version $Revision$ */class HTTP_Download{ // {{{ protected member variables /** * Path to file for download * * @see HTTP_Download::setFile() * @access protected * @var string */ var $file = ''; /** * Data for download * * @see HTTP_Download::setData() * @access protected * @var string */ var $data = null; /** * Resource handle for download * * @see HTTP_Download::setResource() * @access protected * @var int */ var $handle = null; /** * Whether to gzip the download * * @access protected * @var bool */ var $gzip = false; /** * Whether to allow caching of the download on the clients side * * @access protected * @var bool */ var $cache = true; /** * Size of download * * @access protected * @var int */ var $size = 0; /** * Last modified * * @access protected * @var int */ var $lastModified = 0; /** * HTTP headers * * @access protected * @var array */ var $headers = array( 'Content-Type' => 'application/x-octetstream', 'Pragma' => 'cache', 'Cache-Control' => 'public, must-revalidate, max-age=0', 'Accept-Ranges' => 'bytes', 'X-Sent-By' => 'PEAR::HTTP::Download' ); /** * HTTP_Header * * @access protected * @var object */ var $HTTP = null; /** * ETag * * @access protected * @var string */ var $etag = ''; /** * Buffer Size * * @access protected * @var int */ var $bufferSize = 2097152; /** * Throttle Delay * * @access protected * @var float */ var $throttleDelay = 0; /** * Sent Bytes * * @access public * @var int */ var $sentBytes = 0; // }}} // {{{ constructor /** * Constructor * * Set supplied parameters. * * @access public * @param array $params associative array of parameters * * <b>one of:</b> * o 'file' => path to file for download * o 'data' => raw data for download * o 'resource' => resource handle for download * <br/> * <b>and any of:</b> * o 'cache' => whether to allow cs caching * o 'gzip' => whether to gzip the download * o 'lastmodified' => unix timestamp * o 'contenttype' => content type of download * o 'contentdisposition' => content disposition * o 'buffersize' => amount of bytes to buffer * o 'throttledelay' => amount of secs to sleep * o 'cachecontrol' => cache privacy and validity * * <br /> * 'Content-Disposition' is not HTTP compliant, but most browsers * follow this header, so it was borrowed from MIME standard. * * It looks like this: <br /> * "Content-Disposition: attachment; filename=example.tgz". * * @see HTTP_Download::setContentDisposition() */ function HTTP_Download($params = array()) { $this->HTTP = &new HTTP_Header; $this->setParams($params); } // }}} // {{{ public methods /** * Set parameters * * Set supplied parameters through its accessor methods. * * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param array $params associative array of parameters * * @see HTTP_Download::HTTP_Download() */ function setParams($params) { foreach((array) $params as $param => $value){ $method = 'set'. $param; if (!method_exists($this, $method)) { return PEAR::raiseError( "Method '$method' doesn't exist.", HTTP_DOWNLOAD_E_INVALID_PARAM ); } $e = call_user_func_array(array(&$this, $method), (array) $value); if (PEAR::isError($e)) { return $e; } } return true; } /** * Set path to file for download * * The Last-Modified header will be set to files filemtime(), actually. * Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_FILE) if file doesn't exist. * Sends HTTP 404 status if $send_404 is set to true. * * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param string $file path to file for download * @param bool $send_404 whether to send HTTP/404 if * the file wasn't found */ function setFile($file, $send_404 = true) { $file = realpath($file); if (!is_file($file)) { if ($send_404) { $this->HTTP->sendStatusCode(404); } return PEAR::raiseError( "File '$file' not found.", HTTP_DOWNLOAD_E_INVALID_FILE ); } $this->setLastModified(filemtime($file)); $this->file = $file; $this->size = filesize($file); return true; } /** * Set data for download * * Set $data to null if you want to unset this. * * @access public * @return void * @param $data raw data to send */ function setData($data = null) { $this->data = $data; $this->size = strlen($data); } /** * Set resource for download * * The resource handle supplied will be closed after sending the download. * Returns a PEAR_Error (HTTP_DOWNLOAD_E_INVALID_RESOURCE) if $handle * is no valid resource. Set $handle to null if you want to unset this. * * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param int $handle resource handle */ function setResource($handle = null) { if (!isset($handle)) { $this->handle = null; $this->size = 0; return true; } if (is_resource($handle)) { $this->handle = $handle; $filestats = fstat($handle); $this->size = $filestats['size']; return true; } return PEAR::raiseError( "Handle '$handle' is no valid resource.", HTTP_DOWNLOAD_E_INVALID_RESOURCE ); } /** * Whether to gzip the download * * Returns a PEAR_Error (HTTP_DOWNLOAD_E_NO_EXT_ZLIB) * if ext/zlib is not available/loadable. * * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param bool $gzip whether to gzip the download */ function setGzip($gzip = false) { if ($gzip && !PEAR::loadExtension('zlib')){ return PEAR::raiseError( 'GZIP compression (ext/zlib) not available.', HTTP_DOWNLOAD_E_NO_EXT_ZLIB ); } $this->gzip = (bool) $gzip; return true; } /** * Whether to allow caching * * If set to true (default) we'll send some headers that are commonly * used for caching purposes like ETag, Cache-Control and Last-Modified. * * If caching is disabled, we'll send the download no matter if it * would actually be cached at the client side. * * @access public * @return void * @param bool $cache whether to allow caching */ function setCache($cache = true) { $this->cache = (bool) $cache; } /** * Whether to allow proxies to cache * * If set to 'private' proxies shouldn't cache the response. * This setting defaults to 'public' and affects only cached responses. * * @access public * @return bool * @param string $cache private or public * @param int $maxage maximum age of the client cache entry */ function setCacheControl($cache = 'public', $maxage = 0) { switch ($cache = strToLower($cache)) { case 'private': case 'public': $this->headers['Cache-Control'] = $cache .', must-revalidate, max-age='. abs($maxage); return true; break; } return false; } /** * Set ETag * * Sets a user-defined ETag for cache-validation. The ETag is usually * generated by HTTP_Download through its payload information. * * @access public * @return void * @param string $etag Entity tag used for strong cache validation. */ function setETag($etag = null) { $this->etag = (string) $etag; } /** * Set Size of Buffer * * The amount of bytes specified as buffer size is the maximum amount * of data read at once from resources or files. The default size is 2M * (2097152 bytes). Be aware that if you enable gzip compression and * you set a very low buffer size that the actual file size may grow * due to added gzip headers for each sent chunk of the specified size. * * Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_PARAM) if $size is not * greater than 0 bytes. * * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param int $bytes Amount of bytes to use as buffer. */ function setBufferSize($bytes = 2097152) { if (0 >= $bytes) { return PEAR::raiseError( 'Buffer size must be greater than 0 bytes ('. $bytes .' given)', HTTP_DOWNLOAD_E_INVALID_PARAM); } $this->bufferSize = abs($bytes); return true; } /** * Set Throttle Delay * * Set the amount of seconds to sleep after each chunck that has been * sent. One can implement some sort of throttle through adjusting the * buffer size and the throttle delay. With the following settings * HTTP_Download will sleep a second after each 25 K of data sent. * * <code> * Array( * 'throttledelay' => 1, * 'buffersize' => 1024 * 25, * ) * </code> * * Just be aware that if gzipp'ing is enabled, decreasing the chunk size * too much leads to proportionally increased network traffic due to added * gzip header and bottom bytes around each chunk. * * @access public * @return void * @param float $seconds Amount of seconds to sleep after each * chunk that has been sent. */ function setThrottleDelay($seconds = 0) { $this->throttleDelay = abs($seconds) * 1000; } /** * Set "Last-Modified" * * This is usually determined by filemtime() in HTTP_Download::setFile() * If you set raw data for download with HTTP_Download::setData() and you * want do send an appropiate "Last-Modified" header, you should call this * method. * * @access public * @return void * @param int unix timestamp */ function setLastModified($last_modified) { $this->lastModified = $this->headers['Last-Modified'] = (int) $last_modified; } /** * Set Content-Disposition header * * @see HTTP_Download::HTTP_Download *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -