Curl kullanarak büyük bir dosya indirme


87

Curl kullanarak uzak dosyayı indirmem gerekiyor.

İşte sahip olduğum örnek kod:

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

Ama büyük dosyaları işleyemez çünkü önce belleğe okur.

Dosyayı doğrudan diske aktarmak mümkün mü?

Yanıtlar:


169
<?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
Yorumunuzu @ yes123 savun, bilmek istiyorum.
Jürgen Paul

8
Yanılıyorsam düzeltin, ancak fwritekullandığınız için verileri gerçekten manuel olarak yapmanız gerektiğini düşünmüyorum CURLOPT_FILE.
Sasha Chedygov

1
@SashaChedygov'un yukarıda işaret ettiği gibi, fwriteAND kullanmanıza gerek yok CURLOPT_FILE. Geçmek $fpyeterlidir. İkisini de yaptım ve 1dosyanın içeriğinin sonunda kaldım .
2013

@Sasha Chedygov ~ evet ihtiyacın yokfwrite
Alireza

5
Görünüşe göre CURLOPT_RETURNTRANSFER'ı ayarlamadan önce CURLOPT_FILE'nin ayarlanması işe yaramıyor, çünkü muhtemelen CURLOPT_FILE, CURLOPT_RETURNTRANSFER'ın ayarlanmasına bağlı. php.net/manual/en/function.curl-setopt.php#99082
Nabi KAZ

25

Bu kullanışlı işlevi kullanıyorum:

4094 baytlık bir adımla indirirseniz, hafızanız dolmaz

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;
}

Kullanım:

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

Daha sonra her şeyin yolunda olup olmadığını kontrol edebilirsiniz:

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

1
@Severus, fopen()yanlış döndürürken http hatasını yakalarsanız ve bunu while döngüsüne koyarsınız (arayın time()ve hesaplayın)
Silviu-Marian

2
cURL zaten bunun çalışan bir uygulamasına sahip (kabul edilen cevaba bakın), neden bir şeyi kendi başınıza uygulamak isteyesiniz?
Petr Peller

2
Çünkü cURL yordamsal arayüzü oldukça kötü
dinamik

ne olursa olsun, stream_copy_to_streamiçeriği manuel olarak kopyalamak yerine kullanıyorum , daha kısa bir kod yapıyor. Ne bu ne de bu işe httpsyaramaz (a'yı şart koşmadığınız sürece $context). Prosedürel stili uyumlu hale getirmek - dosya işlevleri de pek OOP değildir ve eğer bir diziye curl seçeneklerini koyarsanız, yine de çok daha temiz görünecektir.
ashein

Https ile test ettim, harika çalışıyor !!!, @ dinamik yardımın için teşekkürler.
Özal Zarbaliyev

6

Belirtilen URL'nin içeriğini indirmek istiyorsanız aşağıdaki kodu da bir dosyaya kaydetmek istiyorsanız bulun.

<?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 sunucusundan dosya indirmek istiyorsanız, php FTP uzantısını kullanabilirsiniz. Lütfen aşağıdaki kodu bulun:

<?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

ne zaman curlbüyük bir dosya indirmek için kullanılır, sonra CURLOPT_TIMEOUTsizin için setine sahip ana seçenektir.

CURLOPT_RETURNTRANSFER pdf / csv / image vb. gibi bir dosya almanız durumunda doğru olması gerekir.

Daha fazla ayrıntıyı burada bulabilirsiniz (doğru url) Curl Doc

Bu sayfadan:

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


2

Dosya sisteminde bir geçici dosya oluşturan ve her şey yolunda giderse indirilen dosyanın yolunu döndüren bu işlevi kullanabilirsiniz:

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.