思路步驟
* 定義參數
* 魔術方法
* 執行下載
* 獲取設置屬性函數
* 獲取設置文件mime 類型
* 獲取設置下載文件名
* 設置header
* 下載函數
實現代碼
class DownFile{ // 定義參數 public $data; // 下載的數據或文件名 public $is_con=false; // 是否是下載內容 public $down_file_name; // 下載后的文件名 public $mime_type; //下載時設置的文件類型 public $file_del=false; // 下載完成后是否刪除服務器文件 private $file_ext='octet-stream'; // 下載文件時設置的默認文件后綴(獲取不到文件類型時設置) private $default_mime_type='application/'; // 下載時設置的默認文件類型 // 魔術方法-- 對象參數賦值 public function __get($name) { return $this->name; } public function __set($name,$value) { if(!isset($this->name)) { exit("no is $name attr"); } $this->name = $value; } public function __isset($name) { return isset($this->name); } // 執行下載 public function output($data=null,$down_file_name=null,$is_con=null) { // 初始化賦值基本數據 if(!empty($data)) $this->data=$data; if(isset($is_con)) $this->is_con=$is_con; // 如果下載的不是數據 並且不是文件 拋出異常 if (!$this->is_con && !is_file($this->data)) { throw new Exception('file not exists:' . $this->data); } ob_end_clean(); // 下載文件名 $this->down_file_name($down_file_name); if($this->is_con) { $this->mime_type=$this->default_mime_type.$this->file_ext; $file_size=strlen($this->data); $this->header($file_size); // 如果數據量過多建議 while 方式輸出 /*$read_size=0; $buffer=1024; //設置一次讀取的字節數,每讀取一次,就輸出數據(即返回給瀏覽器) while ($read_size<=$file_size) { echo substr($this->data,$read_size,$buffer); $read_size+=$buffer; }*/ // 如果數據量小使用以下方式輸出 echo $this->data; }else if(is_file($this->data)) { $this->get_mime_type(); $this->down_file(filesize($this->data)); } } // 獲取設置文件mime 類型 private function get_mime_type() { if(empty($this->mime_type)) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $this->mime_type=finfo_file($finfo, $this->data); if(empty($this->mime_type)) $this->mime_type=$this->default_mime_type.$this->file_ext; } } // 獲取設置下載文件名 private function down_file_name($down_file_name) { if(!empty($down_file_name)) $this->down_file_name=$down_file_name; else { if(empty($this->down_file_name)) $this->down_file_name=time().$this->file_ext; } } // 設置header private function header($f_size) { header("Content-type:".$this->mime_type); header("Accept-Ranges:bytes"); header("Accept-Length:".$f_size); header("Content-Disposition:attachment;filename=".$this->down_file_name); header("Content-Transfer-Encoding:binary"); header("Cache-Control:no-cache,no-store,max-age=0,must-revalidate"); header("Pragma:no-cache"); } // 下載文件函數 private function down_file($f_size) { $this->header($f_size); if(!$this->file_del) { // 如果文件過大建議使用 while 方式讀取輸出 /*$fp=fopen($this->data,"r"); $buffer=1024; //設置一次讀取的字節數,每讀取一次,就輸出數據(即返回給瀏覽器) while(!feof($fp)) { $file_con=fread($fp,$buffer); // fread 指針自動下移 echo $file_con; } fclose($fp);*/ // 如果數據量小直接輸出 readfile($this->data); }else { $fp=fopen($this->data,"r"); $buffer=1024; //設置一次讀取的字節數,每讀取一次,就輸出數據(即返回給瀏覽器) $file_count=0; //讀取的總字節數 //向瀏覽器返回數據 while(!feof($fp) && $file_count<$f_size){ $file_con=fread($fp,$buffer); $file_count+=$buffer; echo $file_con; } fclose($fp); //下載完成后刪除壓縮包,臨時文件夾 if($file_count >= $f_size) { @unlink($this->data); } } } }
調用示例
$f=new DownFile(); //$f->output('1.png','2.png'); // 參數調用-- 下載文件 //$f->output('測試數據下載直接生成文件','2.txt',true); // 參數調用-- 下載數據直接生成文件 // 對象方式調用 /*$f->data='1.html'; $f->down_file_name='2.html'; //$f->file_del=true; // 下載完成后刪除服務器遠程文件 $f->output();*/ $f->data='對象方式調用'.PHP_EOL.'測試數據下載直接生成文件'; $f->down_file_name='2.txt'; $f->is_con=true; $f->output();