Tải xuống tệp lớn bằng curl


87

Tôi cần tải xuống tệp từ xa bằng curl.

Đây là mã mẫu tôi có:

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

Nhưng nó không thể xử lý các tệp lớn, vì nó đọc vào bộ nhớ trước.

Có thể truyền tệp trực tiếp vào đĩa không?

Câu trả lời:


168
<?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
Bảo vệ bình luận của bạn @ yes123, tôi muốn biết.
Jürgen Paul

8
Hãy sửa cho tôi nếu tôi sai, nhưng tôi không nghĩ rằng bạn thực sự cần phải xử fwritelý dữ liệu theo cách thủ công vì bạn đang sử dụng CURLOPT_FILE.
Sasha Chedygov

1
Như @SashaChedygov đã chỉ ra ở trên, bạn không cần sử dụng fwriteAND CURLOPT_FILE. Vượt qua $fplà đủ. Tôi đã làm cả hai và kết thúc với 1phần cuối của nội dung trong tệp.
kẹp giấy vào

@Sasha Chedygov ~ có bạn không cần sựfwrite
Alireza

5
Có vẻ như việc đặt CURLOPT_FILE trước khi đặt CURLOPT_RETURNTRANSFER không hoạt động, có lẽ vì CURLOPT_FILE phụ thuộc vào việc CURLOPT_RETURNTRANSFER đang được đặt. php.net/manual/en/ Chức năng.curl
Nabi KAZ

25

Tôi sử dụng chức năng tiện dụng này:

Bằng cách tải xuống với bước 4094 byte, nó sẽ không làm đầy bộ nhớ của bạn

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

Sử dụng:

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

Sau đó, bạn có thể kiểm tra xem mọi thứ có ổn không với:

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

1
@Severus bạn bắt http lỗi như fopen()trở về sai và thời gian chờ bạn đặt nó trong vòng lặp while (gọi time()và làm phép tính)
Silviu-Marian

2
cURL đã có triển khai hoạt động của điều này (xem câu trả lời được chấp nhận), tại sao bạn muốn triển khai một cái gì đó của riêng mình?
Petr Peller

2
Vì giao diện thủ tục cURL khá tệ
động

vì những gì nó đáng giá, tôi đã sử dụng stream_copy_to_streamthay vì sao chép nội dung theo cách thủ công, hãy tạo một đoạn mã ngắn hơn. Cả cái này và cái kia đều không hoạt động với https(trừ khi bạn quy định a $context). Phong cách thủ tục quan tâm - các hàm tệp cũng không quá OOP và nếu bạn đặt các tùy chọn cuộn tròn trong một mảng, dù sao thì nó cũng trông gọn gàng hơn.
ashein

Tôi đã thử nghiệm nó với một https, hoạt động tuyệt vời !!!, Cảm ơn bạn đã giúp đỡ @dynamic.
Ozal Zarbaliyev

6

Tìm mã bên dưới nếu bạn muốn tải xuống nội dung của URL được chỉ định cũng như muốn lưu nó vào một tệp.

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

Nếu bạn muốn tải xuống tệp từ máy chủ FTP, bạn có thể sử dụng phần mở rộng php FTP. Vui lòng tìm mã dưới đây:

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

Khi nào curlđược sử dụng để tải xuống một tệp lớn thì đó CURLOPT_TIMEOUTlà tùy chọn chính mà bạn phải đặt.

CURLOPT_RETURNTRANSFER phải đúng trong trường hợp bạn nhận được tệp như pdf / csv / image, v.v.

Bạn có thể tìm thấy thêm chi tiết ở đây (url chính xác) Curl Doc

Từ trang đó:

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 cũng có thể đi qua các ví dụ viết blog liên quan đến download file với curl cơ bản curl hiểu biết
Pandey Prashant

2

Bạn có thể sử dụng chức năng này, tạo một tệp tạm thời trong hệ thống tệp và trả về đường dẫn đến tệp đã tải xuống nếu mọi thứ hoạt động tốt:

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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.