2010-09-10 61 views
1

我想找到一個解決方案,直接得到像wget這樣的文件,而不是從流中讀取並寫入到另一個文件,但我不確定是否這樣是可能的。我怎樣才能用Zend_Http_Client或其他庫下載文件

有什麼建議嗎?

+0

您是否嘗試過使用PHP的CURL實現? – 2010-09-10 11:29:14

+0

我猜cURL具有寫入文件的相同方法,它從源讀取什麼。我想下載文件而不打開它並重新創建它的MIME類型和這樣的東西。 – 2010-09-10 11:36:43

回答

3

我還發現copy,它允許一個文件從URL直接複製到磁盤,是一個oneliner沒有捲曲或複雜需要創建一個空文件,在其中傳輸file_get_contents的內容。

copy($file_url, $localpath); 
+0

你不必創建一個空文件。只需提供一個可寫的文件路徑。 – 2010-09-10 18:19:40

+0

不知道copy()解決方案...會做一些基準測試。聽起來很有趣。 – 2010-09-10 18:37:25

+0

基準測試exec wget,copy()和curl ...所有的運行時和內存使用情況幾乎相同。編輯我的答案供以後參考。感謝您的副本() - 解決方案+1。 – 2010-09-10 19:14:04

1

使用CURLOPT_FILE您可以將一些文件流直接寫入打開的文件句柄(請參閱curl_setopt)。根據您的意見

/** 
* @param string $url 
* @param string $destinationFilePath 
* @throws Exception 
* @return string 
*/ 
protected function _downloadFile($url, $destinationFilePath) 
{ 
    $fileHandle = fopen($destinationFilePath, 'w'); 

    if (false === $fileHandle) { 
     throw new Exception('Could not open filehandle'); 
    } 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_FILE, $fileHandle); 

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

    if (false === $result) { 
     throw new Exception('Could not download file'); 
    } 

    return $destinationFilePath; 
} 

編輯:
如果你想有一個oneliner或者想使用wget調用它通過exec()system()像這樣:

exec('wget http://google.de/ -O google.html -q') 

編輯以供日後參考:

<?php 
function downloadCurl($url, $destinationFilePath) 
{ 
    $fileHandle = fopen($destinationFilePath, 'w'); 

    if (false === $fileHandle) { 
     throw new Exception('Could not open filehandle'); 
    } 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_FILE, $fileHandle); 

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

    if (false === $result) { 
     throw new Exception('Could not download file'); 
    } 
} 


function downloadCopy($url, $destinationFilePath) 
{ 
    if (false === copy($url, $destinationFilePath)) { 
     throw new Exception('Could not download file'); 
    } 
} 

function downloadExecWget($url, $destinationFilePath) 
{ 
    $output = array(); 
    $return = null; 
    exec(sprintf('wget %s -O %s -q', escapeshellarg($url), escapeshellarg($destinationFilePath)), $output, $return); 

    if (1 === $return) { 
     throw new Exception('Could not download file'); 
    } 
} 

這三種方法的運行時間和內存使用量幾乎相等。
使用最適合您的環境的任何東西。

+0

一樣。我想下載該文件不要讀取它並重新創建它。 – 2010-09-10 12:05:23

+0

Elzo:該文件直接寫入本地文件。這跟wget一樣。 – 2010-09-10 12:12:17

+0

不是直接。我必須打開一個文件,並打開它。沒有? wget是oneliner。 – 2010-09-10 13:17:04

0
$c = file_get_contents('http://www.example.com/my_file.tar.gz'); 

現在寫$ C到本地文件...

+0

閱讀我的評論。 file_get_contents給了我一個字符串,我必須寫入一個文件。我希望文件不要創建副本。 – 2010-09-10 12:02:37

+0

我不明白「我想要的文件」...在一個PHP變量?在文件系統上?其中... – Riba 2010-09-10 16:53:57

+0

是的,在文件系統上。那裏的文件留下來。你在變量或內存中有什麼不是文件 – 2010-09-10 18:10:41

1

file_put_contents($ LOCAL_PATH,的file_get_contents($ FILE_URL));

是一個內襯太;-)

與上面的代碼唯一的問題可能是非常大的文件:一份可能是在這種情況下更好,還能看到http://www.php.net/manual/en/function.copy.php#88520

一些測試需要...