使用 PHP 一次下载多个文件


Using PHP to download multi files at one time

class Transfer {
/**
 * @access private
 * @var integer
 */
private $mDownStart;
/**
 * @access private
 * @var integer
 */
private $mFileSize;
/**
 * @access private
 * @var integer
 */
private $mFileHandle;
/**
 * @access private
 * @var string
 */
private $mFilePath;
/**
 * @access private
 * @var string
 */
private $mFileName;
/**
 * @access public
 * @return void
 **/
public function __construct() {
}
/**
 * @access public
 * @return void
 **/
public function Down($pFilePath, $pFileName = '') {
    $this->mFilePath = $pFilePath;
    if (!$this->iniFile())
        $this->sendError();
    $this->mFileName = empty($pFileName) ? $this->getFileName() : $pFileName;
    $this->iniFile();
    $this->setStart();
    $this->setHeader();
    $this->send();
    fclose($this->mFileHandle);
}
/**
 * @access private
 * @return boolean
 **/
private function iniFile() {
    if (!is_file($this->mFilePath))
        return false;
    $this->mFileHandle = fopen($this->mFilePath, 'rb');
    $this->mFileSize = filesize($this->mFilePath);
    return true;
}
/**
 * @access private
 * @return void
 **/
private function setStart() {
    if (isset($_SERVER['HTTP_RANGE'])) {
        preg_match("/^bytes=([0-9]+)-$/i", $_SERVER['HTTP_RANGE'], $match);
        $this->mDownStart = $match[1];
        fseek($this->mFileHandle, $this->mDownStart);
    } else {
        $this->mDownStart = 0;
    }
}
/**
 * @access private
 * @return void
 **/
private function setHeader() {
    @header("Cache-control: public");
    @header("Pragma: public");
    header("Content-Length: " . ($this->mFileSize - $this->mDownStart));
    if ($this->mDownStart > 0) {
        @header("HTTP/1.1 206 Partial Content");
        header("Content-Range: bytes " . $this->mDownStart . "-" . ($this->mFileSize - 1) . "/" . $this->mFileSize);
    } else {
        header("Accept-Range: bytes");
    }
    @header("Content-Type: application/octet-stream");
    @header("Content-Disposition: attachment;filename=" . $this->mFileName);
}
/**
 * @access private
 * @return string
 **/
private function getFileName() {
    return basename($this->mFilePath);
}
/**
 * @access private
 * @return void
 **/
private function send() {
    // fpassthru($this->mFileHandle);
    while (!feof($this->mFileHandle)) {
        set_time_limit(0);
        $buffer = fread($this->mFileHandle, 1024 * 1024);
        echo $buffer;
        flush();
        ob_flush();
    }
}
/**
 * @access public
 * @return void
 **/
public function sendError() {
    @header("HTTP/1.0 404 Not Found");
    @header("Status: 404 Not Found");
    exit();
}
}

这是我如何使用它,

 $transfer = new Transfer;
 $transfer->Down('D:'Pro lab'Aptana workspace'ezine'ezine'201202161811'VOL_001_201202161811.zip');

当我尝试打开IE的两个选项卡来运行脚本时。但是,它们无法同时下载。它们按一个接一个的顺序排列。但是,当我将文件放在 apache 根目录中时。仍然使用IE的两个选项卡下载它们,可以同时下载它们。我想知道,为什么会这样?

我想如果PHP中有任何类型的"锁",以限制同一客户端同时下载相同的资源?

如果您尝试从两个窗口访问同一脚本,并且第二个脚本被锁定,则在大多数情况下,这表示会话锁定。 您是否在使用会话? 如果是这样,您需要:

  1. 不使用会话 - 或 -
  2. 在开始下载之前调用session_write_close以释放会话锁定。

请注意,调用session_write_close后对会话所做的任何更改都将丢失。