2012-02-16 27 views
2
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(); 
} 
} 

這裏下載文件多是我如何使用它,使用PHP一次

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

當我嘗試打開IE的兩個標籤來運行該腳本。但是,他們不能同時下載。他們是在一個接一個的順序。 但是,當我把文件放在apache根目錄下。仍然使用IE的兩個標籤下載它們,它們可以同時下載。 我想知道爲什麼會發生這種情況?

我猜如果在PHP中有任何一種「鎖定」,限制同一個客戶端同時下載相同的資源??

+1

您是否有強制會話在子目錄中啓動的.htaccess或其他重寫?如果存在活動會話,則一次只能有一個連接工作 - 其他連接將阻塞,直到會話被釋放。 – 2012-02-16 14:54:08

+0

我認爲,這裏沒有活動會話。 – 2012-02-16 15:07:28

+1

我想這不是一個下載的東西,它是一個PHP的東西。爲了防止每個會話負載過重(並且每個通過http的呼叫都是會話),可能會同時執行一個腳本。您可以將文件寫入臨時文件夾並直接重定向到該文件,而不是通過PHP傳遞整個文件。 – Armin 2012-02-16 15:13:31

回答

0

如果您嘗試從兩個窗口訪問相同的腳本並鎖定第二個腳本,則在大多數情況下,這是會話鎖定的指示。你在使用會話嗎?如果是這樣,你需要:

  1. 不使用會話 - 或 -
  2. 呼叫session_write_close開始下載,以釋放會話鎖之前。

請注意,調用session_write_close後會話的任何更改都將丟失。

+0

Ijust將Transfer類保存在Transfer.php文件中。而訪問者通過http://127.0.0.1/Transfer.php,我不會在這裏使用session。 – 2012-02-17 02:33:56