2011-06-20 106 views
73

我需要使用捲曲下載遠程文件。使用捲曲下載大文件

這裏的示例代碼,我有:

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

$st = curl_exec($ch); 
$fd = fopen($tmp_name, 'w'); 
fwrite($fd, $st); 
fclose($fd); 

curl_close($ch); 

但它不能處理大文件,因爲它讀取內存第一。

是否有可能將文件直接流式傳輸到磁盤?

回答

139
<?php 
set_time_limit(0); 
//This is the file where we save the information 
$fp = fopen (dirname(__FILE__) . '/localfile.tmp', 'w+'); 
//Here is the file we are downloading, replace spaces with %20 
$ch = curl_init(str_replace(" ","%20",$url)); 
curl_setopt($ch, CURLOPT_TIMEOUT, 50); 
// write curl response to file 
curl_setopt($ch, CURLOPT_FILE, $fp); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
// get curl response 
curl_exec($ch); 
curl_close($ch); 
fclose($fp); 
?> 
+4

捍衛你的評論@ yes123,我很想知道。 – Michelle

+7

糾正我,如果我錯了,但我不認爲你實際上需要手動'fwrite'數據,因爲你使用'CURLOPT_FILE'。 –

+1

正如@SashaChedygov在上面指出的,你不需要使用'fwrite'和'CURLOPT_FILE'。傳遞'$ fp'就足夠了。我做了兩個,最後在文件內容的末尾加上了'1'。 – paperclip

20

我用這個方便的功能:

通過與4094字節的步驟下載它,它不會完全你的記憶

function download($file_source, $file_target) { 
    $rh = fopen($file_source, 'rb'); 
    $wh = fopen($file_target, 'w+b'); 
    if (!$rh || !$wh) { 
     return false; 
    } 

    while (!feof($rh)) { 
     if (fwrite($wh, fread($rh, 4096)) === FALSE) { 
      return false; 
     } 
     echo ' '; 
     flush(); 
    } 

    fclose($rh); 
    fclose($wh); 

    return true; 
} 

用法:

 $result = download('http://url','path/local/file'); 

就可以檢查,如果一切可以:

 if (!$result) 
     throw new Exception('Download error...'); 
+6

thx但我需要與捲曲:) – kusanagi

+1

我會怎樣,趕上HTTP錯誤,並使其超時? – Michelle

+1

@Severus你抓到http錯誤爲'fopen()'返回false和超時你把它放在while循環中(調用'time()'並做數學運算) –

5

查找下面的代碼,如果你想下載指定的URL的內容也想保存到一個文件。

<?php 
$ch = curl_init(); 
/** 
* Set the URL of the page or file to download. 
*/ 
curl_setopt($ch, CURLOPT_URL,'http://news.google.com/news?hl=en&topic=t&output=rss'); 

$fp = fopen('rss.xml', 'w+'); 
/** 
* Ask cURL to write the contents to a file 
*/ 
curl_setopt($ch, CURLOPT_FILE, $fp); 

curl_exec ($ch); 

curl_close ($ch); 
fclose($fp); 
?> 

如果要從FTP服務器下載文件,可以使用php FTP擴展。請看以下代碼:

<?php 
$SERVER_ADDRESS=""; 
$SERVER_USERNAME=""; 
$SERVER_PASSWORD=""; 
$conn_id = ftp_connect($SERVER_ADDRESS); 

// login with username and password 
$login_result = ftp_login($conn_id, $SERVER_USERNAME, $SERVER_PASSWORD); 

$server_file="test.pdf" //FTP server file path 
$local_file = "new.pdf"; //Local server file path 

##----- DOWNLOAD $SERVER_FILE AND SAVE TO $LOCAL_FILE--------## 
if (ftp_get($conn_id, $local_file, $server_file, FTP_BINARY)) { 
    echo "Successfully written to $local_file\n"; 
} else { 
    echo "There was a problem\n"; 
} 

ftp_close($conn_id); 
?> 
2
curl用於下載大文件

然後CURLOPT_TIMEOUT是你必須爲設置的主要選擇。

CURLOPT_RETURNTRANSFER必須是萬一你越來越像PDF/CSV /圖像文件真實等

您可能會發現進一步的細節在這裏(正確的URL)Curl Doc

在這個頁面:

curl_setopt($request, CURLOPT_TIMEOUT, 300); //set timeout to 5 mins 

curl_setopt($request, CURLOPT_RETURNTRANSFER, true); // true to get the output as string otherwise false 
+0

你也可以通過關於curl下載文件的博客例子[理解curl基礎知識](http://prashantpandeytech.blogspot.in /2012/10/there-is-common-problem-when-large-site.html) –

+0

錯誤的網址,它會載入其他內容。 – user427969

1

您可以使用此功能,它創建於文件系統中的臨時文件,如果一切正常的路徑返回到下載的文件:

function getFileContents($url) 
{ 
    // Workaround: Save temp file 
    $img = tempnam(sys_get_temp_dir(), 'pdf-'); 
    $img .= '.' . pathinfo($url, PATHINFO_EXTENSION); 

    $fp = fopen($img, 'w+'); 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 

    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_FILE, $fp); 
    curl_setopt($ch, CURLOPT_HEADER, false); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

    $result = curl_exec($ch); 
    curl_close($ch); 

    fclose($fp); 

    return $result ? $img : false; 
}