การดาวน์โหลดไฟล์ขนาดใหญ่โดยใช้ curl


87

ฉันต้องการดาวน์โหลดไฟล์ระยะไกลโดยใช้ 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);

แต่มันไม่สามารถจัดการไฟล์ขนาดใหญ่ได้เพราะมันอ่านหน่วยความจำก่อน

เป็นไปได้ไหมที่จะสตรีมไฟล์ไปยังดิสก์โดยตรง

คำตอบ:


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
ปกป้องความคิดเห็นของคุณ @ yes123 ฉันสนใจที่จะรู้
Jürgen Paul

8
ถูกต้องฉันหากฉันผิด แต่ผมไม่คิดว่าคุณต้องการจริงด้วยตนเองข้อมูลนับตั้งแต่ที่คุณกำลังใช้fwrite CURLOPT_FILE
Sasha Chedygov

1
ในฐานะที่เป็น @SashaChedygov ได้ชี้ให้เห็นข้างต้นคุณไม่จำเป็นต้องใช้และfwrite CURLOPT_FILEผ่าน$fpก็เพียงพอแล้ว ฉันทำทั้งสองอย่างและลงเอยด้วย1ตอนท้ายของเนื้อหาในไฟล์
คลิปหนีบกระดาษ

@Sasha Chedygov ~ ใช่คุณไม่ต้องการfwrite
Alireza

5
ดูเหมือนว่าการตั้งค่า CURLOPT_FILE ก่อนการตั้งค่า CURLOPT_RETURNTRANSFER ไม่ได้ผลน่าจะเป็นเพราะ CURLOPT_FILE ขึ้นอยู่กับ CURLOPT_RETURNTRANSFER ที่ตั้งค่าไว้ 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()ส่งคืนเท็จและหมดเวลาที่คุณใส่ไว้ในลูป while (โทรtime()และทำคณิตศาสตร์)
Silviu-Marian

2
cURL มีการใช้งานสิ่งนี้อยู่แล้ว (ดูคำตอบที่ได้รับการยอมรับ) ทำไมคุณถึงต้องการใช้งานด้วยตัวคุณเอง
Petr Peller

2
เนื่องจากอินเทอร์เฟซขั้นตอน cURL ค่อนข้างแย่
ไดนามิก

สำหรับสิ่งที่คุ้มค่าฉันใช้stream_copy_to_streamแทนที่จะคัดลอกเนื้อหาด้วยตนเองทำให้รหัสสั้นลง สิ่งนี้หรือไม่ได้ผลhttps(เว้นแต่คุณจะกำหนดก$context.) รูปแบบขั้นตอนการแสดงร่วมกัน - ฟังก์ชั่นไฟล์ก็ไม่ค่อย OOP เช่นกันและถ้าคุณใส่ตัวเลือก curl ในอาร์เรย์มันก็จะดูสะอาดขึ้นอยู่ดี
ashein

ฉันทดสอบด้วย 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 เป็นต้น

คุณสามารถดูรายละเอียดเพิ่มเติมได้ที่นี่ (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

คุณยังสามารถดูตัวอย่างบล็อกเกี่ยวกับการดาวน์โหลดไฟล์ด้วย curl ทำความเข้าใจพื้นฐาน curl
Prashant

2

คุณสามารถใช้ฟังก์ชันนี้ซึ่งจะสร้าง tempfile ในระบบไฟล์และส่งคืนเส้นทางไปยังไฟล์ที่ดาวน์โหลดหากทุกอย่างทำงานได้ดี:

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.