Подтвердить что ты не робот

Как установить максимальный размер загрузки 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() загружает изображение, чтобы вернуть его размер, поэтому его нельзя использовать.

4b9b3361

Ответ 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 отключен.