使用PHP下載檔案
使用PHP指令碼來下載檔案,無非是通過兩種方式,一種是使用system、exec等即有的函式呼叫系統自帶的下載工具,比如 wget 之類的來下載檔案,還有一種是使用php本身利用Socket來下載檔案,我選擇第二種方式。
使用Socket下載檔案,首先如果是http協議的檔案,必須明白HTTP協議的執行過程,如果是FTP協議的則要了解ftp協議執行過程,比較繁瑣。比如HTTP協議訪問一個檔案的程式碼:(來自手冊)
<?php
$fp = fsockopen(“www.example.com”, 80, $errno, $errstr, 30);
if (!$fp) {
echo “$errstr ($errno)<br />
“;
} else {
$out = “GET / HTTP/1.1
“;
$out .= “Host: www.example.com
“;
$out .= “Connection: Close
“;
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
我們為了簡單起見,使用fopen直接訪問遠端檔案來達到目的,同事又能夠訪問http,也能訪問ftp,比較合適。當然,如果按照上面的思路來說,也可以使用ftp的函式庫來實現。
我們使用fopen函式來完成我們的工作,實現瞭如下程式碼:
#! /usr/bin/php
<?php
error_reporting(0);
set_time_limit(0);
//無引數則給出提示
if ($argc < 2){
echo “Usage: “. $argv[0] .” URL [Destination]
“;
exit();
}
//設定獲取基本變數
$url = $argv[1];
$save_path = $argv[2] ? $argv[2] : “./”;
$file_name = array_pop(explode(“/”, $url));
$localfile = $save_path . $file_name;
//檢查變數
if (!check_url($url)){
exit(“Error: URL “. $url .” invalid.
“);
}
if (file_exists($localfile)){
exit(“Error: local file “. $localfile .” exists.
“);
}
//開啟遠端檔案
$fp = fopen($url, “rb”);
if (!$fp){
exit(“Error: Download “. $url .” failed.
“);
}
//開啟本地檔案
$sp = fopen($localfile, “wb”);
if (!$sp){
exit(“Error: Open local file “. $localfile .” failed.
“);
}
//下載遠端檔案
echo “Downloading, please waiting…
“;
while (!feof($fp)){
$tmpfile .= fread($fp, 1024);
}
//儲存檔案到本地
fwrite($sp, $tmpfile);
fclose($fp);
fclose($sp);
echo “Download file “. $file_name .” succeed!
“;
/* 檢查URL合法性函式 */
function check_url($url){
return preg_match(“/^(http|ftp)(://)([a-zA-Z0-9-_]+[./]+[w-_/]+.*)+$/i”, $url);
}
?>
我們把以上程式碼儲存為 download.php 檔案,在Linux/Unix下記得要加上可執行屬性:
chmod +x download.php
另外,PHP指令碼引擎的路徑必須是 /usr/bin/php ,如果不是,請自行修改第一行為實際的PHP引擎路徑,比如:
#! /usr/local/php/bin/php
使用上面的指令碼來下載檔案:
download.php 遠端檔案 儲存路徑
如把Google Talk程式下載到我們的 /tmp 目錄下:
download.php http://dl.google.com/googletalk/googletalk-setup.exe /tmp/
如果不出錯,等待一會就能夠在 /tmp/ 目錄下看到 googletalk-setup.exe 檔案。
能夠改進的就是支援更多協議、需要驗證的能夠輸入使用者名稱密碼、有下載進度條。至於斷點續傳和多執行緒對於PHP來說還不太現實,有興趣的可以自己加深一步。
PS: 我另外發現一個更強的HTTP下載類,是dedeCMS的作者IT柏拉圖寫的:
<?
/*=======================================
// 織夢Http下載類
// 織夢之旅 www.dedecms.com
=======================================*/
class DedeHttpDown
{
var $m_url = “”;
var $m_urlpath = “”;
var $m_scheme = “http”;
var $m_host = “”;
var $m_port = “80”;
var $m_user = “”;
var $m_pass = “”;
var $m_path = “/”;
var $m_query = “”;
var $m_fp = “”;
var $m_error = “”;
var $m_httphead = “” ;
var $m_html = “”;
//
//初始化系統
//
function PrivateInit($url)
{
$urls = “”;
$urls = @parse_url($url);
$this->m_url = $url;
if(is_array($urls))
{
$this->m_host = $urls[“host”];
if(!empty($urls[“scheme”])) $this->m_scheme = $urls[“scheme”];
if(!empty($urls[“user”])){
$this->m_user = $urls[“user”];
}
if(!empty($urls[“pass”])){
$this->m_pass = $urls[“pass”];
}
if(!empty($urls[“port”])){
$this->m_port = $urls[“port”];
}
if(!empty($urls[“path”])) $this->m_path = $urls[“path”];
$this->m_urlpath = $this->m_path;
if(!empty($urls[“query”]))
{
$this->m_query = $urls[“query”];
$this->m_urlpath .= “?”.$this->m_query;
}
}
}
//
//開啟指定網址
//
function OpenUrl($url)
{
//重設各引數
$this->m_url = “”;
$this->m_urlpath = “”;
$this->m_scheme = “http”;
$this->m_host = “”;
$this->m_port = “80”;
$this->m_user = “”;
$this->m_pass = “”;
$this->m_path = “/”;
$this->m_query = “”;
$this->m_error = “”;
$this->m_httphead = “” ;
$this->m_html = “”;
$this->Close();
//初始化系統
$this->PrivateInit($url);
$this->PrivateStartSession();
}
//
//獲得某操作錯誤的原因
//
function printError()
{
echo “錯誤資訊:”.$this->m_error;
echo “具體返回頭:<br>”;
foreach($this->m_httphead as $k=>$v)
{ echo “$k => $v <br>
“; }
}
//
//判別用Get方法傳送的頭的應答結果是否正確
//
function IsGetOK()
{
if( ereg(“^2”,$this->GetHead(“http-state”)) )
{ return true; }
else
{
$this->m_error .= $this->GetHead(“http-state”).” – “.$this->GetHead(“http-describe”).”<br>”;
return false;
}
}
//
//看看返回的網頁是否是text型別
//
function IsText()
{
if(ereg(“^2”,$this->GetHead(“http-state”))
&& eregi(“^text”,$this->GetHead(“content-type”)))
{ return true; }
else
{
$this->m_error .= “內容為非文字型別<br>”;
return false;
}
}
//
//判斷返回的網頁是否是特定的型別
//
function IsContentType($ctype)
{
if(ereg(“^2”,$this->GetHead(“http-state”))
&& $this->GetHead(“content-type”)==strtolower($ctype))
{ return true; }
else
{
$this->m_error .= “型別不對 “.$this->GetHead(“content-type”).”<br>”;
return false;
}
}
//
//用Http協議下載檔案
//
function SaveToBin($savefilename)
{
if(!$this->IsGetOK()) return false;
if(@feof($this->m_fp))
{ $this->m_error = “連線已經關閉!”; return false; }
$fp = fopen($savefilename,”w”) or die(“寫入檔案 $savefilename 失敗!”);
while(!feof($this->m_fp)){
@fwrite($fp,fgets($this->m_fp,256));
}
@fclose($this->m_fp);
return true;
}
//
//儲存網頁內容為Text檔案
//
function SaveToText($savefilename)
{
if($this->IsText()) $this->SaveBinFile($savefilename);
else return “”;
}
//
//用Http協議獲得一個網頁的內容
//
function GetHtml()
{
if(!$this->IsText()) return “”;
if($this->m_html!=””) return $this->m_html;
if(!$this->m_fp||@feof($this->m_fp)) return “”;
while(!feof($this->m_fp)){
$this->m_html .= fgets($this->m_fp,256);
}
@fclose($this->m_fp);
return $this->m_html;
}
//
//開始HTTP會話
//
function PrivateStartSession()
{
if(!$this->PrivateOpenHost()){
$this->m_error .= “開啟遠端主機出錯!”;
return false;
}
if($this->GetHead(“http-edition”)==”HTTP/1.1″) $httpv = “HTTP/1.1”;
else $httpv = “HTTP/1.0”;
fputs($this->m_fp,”GET “.$this->m_urlpath.” $httpv
“);
fputs($this->m_fp,”Host: “.$this->m_host.”
“);
fputs($this->m_fp,”Accept: */*
“);
fputs($this->m_fp,”User-Agent: Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2)
“);
//HTTP1.1協議必須指定文件結束後關閉連結,否則讀取文件時無法使用feof判斷結束
if($httpv==”HTTP/1.1″) fputs($this->m_fp,”Connection: Close
“);
else fputs($this->m_fp,”
“);
$httpstas = fgets($this->m_fp,256);
$httpstas = split(” “,$httpstas);
$this->m_httphead[“http-edition”] = trim($httpstas[0]);
$this->m_httphead[“http-state”] = trim($httpstas[1]);
$this->m_httphead[“http-describe”] = “”;
for($i=2;$i<count($httpstas);$i++){
$this->m_httphead[“http-describe”] .= ” “.trim($httpstas[$i]);
}
while(!feof($this->m_fp)){
$line = str_replace(“””,””,trim(fgets($this->m_fp,256)));
if($line == “”) break;
if(ereg(“:”,$line)){
$lines = split(“:”,$line);
$this->m_httphead[strtolower(trim($lines[0]))] = trim($lines[1]);
}
}
}
//
//獲得一個Http頭的值
//
function GetHead($headname)
{
$headname = strtolower($headname);
if(isset($this->m_httphead[$headname]))
return $this->m_httphead[$headname];
else
return “”;
}
//
//開啟連線
//
function PrivateOpenHost()
{
if($this->m_host==””) return false;
$this->m_fp = @fsockopen($this->m_host, $this->m_port, &$errno, &$errstr,10);
if(!$this->m_fp){
$this->m_error = $errstr;
return false;
}
else{
return true;
}
}
//
//關閉連線
//
function Close(){
@fclose($this->m_fp);
}
}
?>
———————————————————————————-
這個類的使用方法:
下載網頁
<?
$httpdown = new DedeHttpDown();
$httpdown->OpenUrl(“http://www.dedecms.com”);
echo $httpdown->GetHtml();
$httpdown->Close();
?>
如果下載圖片並儲存,可以用
<?
$httpdown = new DedeHttpDown();
$httpdown->OpenUrl(“http://prato.bokele.com/0/0/399/bGluMi5qcGc=.jpg”);
echo $httpdown->SaveBin(“test.jpg”);
$httpdown->Close();
echo “<img src=`test.jpg`>”;
?>
本文轉自部落格園知識天地的部落格,原文連結:使用PHP下載檔案,如需轉載請自行聯絡原博主。
相關文章
- php檔案下載PHP
- php 檔案下載PHP
- PHP檔案下載原理PHP
- [php]檔案下載簡述PHP
- 讓PHP提供更好的檔案下載PHP
- 使用readfile()下載檔案
- PHP下載遠端檔案及獲取檔案內容PHP
- php程式碼生成txt檔案並下載PHP
- PHP:檔案載入PHP
- 如何使用curl命令下載檔案
- 使用 header 頭下載檔案Header
- Golang 使用http Client下載檔案GolangHTTPclient
- 使用jQuery 完成ajax 檔案下載jQuery
- 使用Servlet實現檔案下載Servlet
- 使用SecureCRT上傳下載檔案Securecrt
- PHP開發之檔案的上傳下載PHP
- 通過php下載檔案並重新命名PHP
- 檔案下載統計php程式設計 (轉)PHP程式設計
- 檔案下載
- php 支援斷點續傳的檔案下載類PHP斷點
- 如何使用post請求下載檔案
- PHP遠端下載檔案原理PHP
- 00、下載檔案
- Ajax 下載檔案
- FastApi下載檔案ASTAPI
- MVC 下載檔案MVC
- js 檔案下載JS
- Servlet下載檔案Servlet
- httpWebRequest 檔案下載HTTPWeb
- .net 檔案下載
- HttpClient 下載檔案HTTPclient
- Response下載檔案
- PHP+Mysql統計檔案下載次數例項PHPMySql
- Android–okhttp與php互動,檔案上傳下載AndroidHTTPPHP
- PHP實現檔案下載斷點續傳詳解PHP斷點
- 使用asp下的adodb.stream 下載檔案
- 使用curl斷點續傳下載檔案斷點
- xshell 使用 sftp上傳下載檔案FTP