curlを使用して大きなファイルをダウンロードする


86

curlを使用してリモートファイルをダウンロードする必要があります。

これが私が持っているサンプルコードです:

$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);

ただし、最初にメモリに読み込むため、大きなファイルは処理できません。

ファイルを直接ディスクにストリーミングすることは可能ですか?

回答:


167
<?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);
?>

5
コメント@ yes123を守ってください。知りたいです。
ユルゲンポール

8
私が間違っている場合は修正してください。ただし、を使用しているため、実際fwriteにデータを手動で指定する必要はないと思いますCURLOPT_FILE
Sasha Chedygov

1
@SashaChedygovが上記で指摘したように、fwriteAND を使用する必要はありませんCURLOPT_FILE。合格$fpすれば十分です。私は両方を行い1、ファイルのコンテンツの最後で終わりました。
2013年

@Sasha Chedygov〜はい、あなたは必要ありませんfwrite
Alireza

5
CURLOPT_FILEが設定されているCURLOPT_RETURNTRANSFERに依存しているため、CURLOPT_RETURNTRANSFERを設定する前にCURLOPT_FILEを設定しても機能しないようです。php.net/manual/en/function.curl-setopt.php#99082
Nabi KAZ

25

私はこの便利な機能を使用します:

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...');

1
@Severusはhttpエラーをfopen()false として返し、タイムアウトはwhileループに入れます(呼び出しtime()て計算を行います)
Silviu-Marian

2
cURLにはすでにこれの実用的な実装があります(承認された回答を参照)、なぜ自分で実装したいのですか?
Petr Peller、2013

2
cURL手続き型インターフェースはかなり悪いため
動的

それだけの価値があるので、stream_copy_to_streamコンテンツを手動でコピーする代わりに使用して、短いコードを作成しました。これも機能しませんhttps(あなたがを規定しない限り$context)。手続き型のコンサートスタイル-ファイル関数もOOPにはなりません。配列にcurlオプションを配置すると、とにかく見た目がすっきりします。
ashein 2013年

私はそれをhttpsでテストしましたが、うまく動作します!!!、@ dynamicをご利用いただきありがとうございます。
Ozal Zarbaliyev

6

指定した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);
?>

4

ときcurl、大きなファイルをダウンロードするために使用され、その後CURLOPT_TIMEOUT、あなたがのために設定する必要が主なオプションがあります。

CURLOPT_RETURNTRANSFER pdf / csv / imageなどのファイルを取得する場合は、trueにする必要があります。

詳細については、こちら(正しいURL)をご覧ください。CurlDoc

そのページから:

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

Uはまた、カールしたファイルのダウンロードに関するブログの例を通過することができます理解カールの基礎知識
プラシャント・パンディー

2

この関数を使用して、ファイルシステムに一時ファイルを作成し、すべてが正常に機能した場合にダウンロードしたファイルへのパスを返すことができます。

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.