Как установить максимальный размер загрузки PHP cURL?

Существует ли максимальный размер загрузок PHP cURL? то есть. будет ли cURL завершаться, когда передача достигнет определенного лимита файла?

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);

Это для сайта, который загружает удаленные изображения. Я хочу убедиться, что cURL остановится, когда достигнет определенного предела.

Также мое исследование показывает, что getimagesize() загружает изображение, чтобы вернуть его размер, поэтому его нельзя использовать.

Ответ 1

У меня есть еще один ответ, который лучше всего подходит для ситуации для потомков.

CURLOPT_WRITEFUNCTION хорош для этого, но CURLOPT_PROGRESSFUNCTION является лучшим.

// We need progress updates to break the connection mid-way
curl_setopt($cURL_Handle, CURLOPT_BUFFERSIZE, 128); // more progress info
curl_setopt($cURL_Handle, CURLOPT_NOPROGRESS, false);
curl_setopt($cURL_Handle, CURLOPT_PROGRESSFUNCTION, function(
    $DownloadSize, $Downloaded, $UploadSize, $Uploaded
){
    // If $Downloaded exceeds 1KB, returning non-0 breaks the connection!
    return ($Downloaded > (1 * 1024)) ? 1 : 0;
});

Имейте в виду, что даже если PHP.net заявляет ^ для CURLOPT_PROGRESSFUNCTION:

Обратный вызов принимает пять параметров.

Мои локальные тесты показали только четыре (4) параметра, поскольку 1-й (дескриптор) не присутствует.

Ответ 2

Есть. Я полагаю, что это предел памяти PHP. Поскольку загрузка выполняется в памяти...

Но CURLOPT_FILE и CURLOPT_WRITEHEADER ^ являются вашими друзьями, поскольку они позволяют перенаправить загрузку cURL в потоки.. Это позволяет создавать временные потоки tmpfile() (stream_get_meta_data() предоставляет путь к файлу) и загружать их. И загрузка непосредственно на диск снижает ограничения памяти.

Как только загрузка завершится, вы сможете прочитать эти файлы и сделать то, что вы хотите с ними.

Ответ 3

Сервер не соблюдает заголовок Range. Лучшее, что вы можете сделать, это отменить соединение, как только вы получите больше данных, чем хотите. Пример:

<?php
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1';
$curl_handle = curl_init($curl_url);

$data_string = "";
function write_function($handle, $data) {
global $data_string;
$data_string .= $data;
if (strlen($data_string) > 1000) {
    return 0;
}
else
    return strlen($data);
} 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt ($curl_handle, CURLOPT_WRITEFUNCTION, 'write_function');

curl_exec($curl_handle);

echo $data_string;

Возможно, более чисто, вы можете использовать http-обертку (это также будет использовать завиток, если он был скомпилирован с -with-curlwrappers). В принципе, вы должны вызывать fread в цикле, а затем fclose в потоке, когда вы получили больше данных, чем вы хотели. Вы также можете использовать транспортный поток (откройте поток с помощью fsockopen вместо fopen и отправьте заголовки вручную), если allow_url_fopen отключен.