curl получить удаленный файл и принудительную загрузку одновременно

Я пытаюсь получить удаленный файл и одновременно принудительно загрузить его пользователю. Я не могу вставить код, он слишком длинный. но функция curl работает, но проблема в том, что она ничего не помещает, пока сначала не получит удаленный файл, а затем принудительно не загрузит его пользователю.

Я использую это, чтобы сказать curl, чтобы вернуть обратный вызов

curl_setopt($ch, CURLOPT_READFUNCTION, 'readCallback');

теперь в моей функции readCallback я делаю это:

function readCallback($curl, $stream, $maxRead){
    $read = fgets($stream, $maxRead);
    echo $read;
    return $read;
}

но он не возвращает ничего, что он просто ждет, пока загрузка удаленного файла не будет завершена.

 Danny12 июн. 2012 г., 09:28
echo предназначен для вывода загруженных частей пользователю, а return для curl, потому что он запрашивает возвращаемое значение из обратного вызова
 ThiefMaster♦12 июн. 2012 г., 08:24
Почему ты эхоand вернуть?
 hakre12 июн. 2012 г., 10:36
возможный дубликатExit out of a cURL fetch --- Вы ищете обратный вызов write, смотрите здесь рабочий пример (и как вы можете отладить это):curl CURLOPT_WRITEFUNCTION PHP example

Ответы на вопрос(2)

Попробуйте использовать curl следующим образом:

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);

$msg = new HttpMessage($result);
return $msg->getBody();

Возвращаемое значение - это содержимое запрошенного файла, которое вы можете затем вывести. Так что нет необходимости в обратном вызове.HTTPMessage docs.

 12 июн. 2012 г., 10:49
Да, но отрицательный? Передача должна быть невероятно быстрой, так как это происходит с одного сервера на другой, и, вероятно, намного быстрее, чем ваше клиентское соединение. И вы можете кэшировать эти файлы локально, чтобы следующий пользователь, запрашивающий тот же файл, получил более быстрый ответ. Вы измерили разницу времени загрузки двух методов?
 04 дек. 2015 г., 10:15
Это сработало для меня :)
 Danny13 июн. 2012 г., 20:53
я хочу кешировать их, когда я представляю их пользователю, когда я сам загружаю их на сервер, я позволяю пользователю загружать их с другой стороны, и когда я загружаю их, я могу кэшировать их сам, и скорость пользователей не может быть больше, чем серверы, даже если это я могу ограничить.
 Danny12 июн. 2012 г., 09:29
но разве это не подождет, пока файл завершит загрузку с помощью curl, а затем выведет его?
Решение Вопроса

Попробуйте это, он будет использовать curl, чтобы получить общий размер файла, а затем загрузить частичные фрагменты файла, передавая его пользователю, так как нетwait для curl, чтобы загрузить его сначала, я проверил это с avi, mp4, mp3 и exe, надеюсь, это поможет:

<?php
$file = 'http://example.com/somefile.mp3';
download($file,2000);

/*
Set Headers
Get total size of file
Then loop through the total size incrementing a chunck size
*/
function download($file,$chunks){
    set_time_limit(0);
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-disposition: attachment; filename='.basename($file));
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Expires: 0');
    header('Pragma: public');
    $size = get_size($file);
    header('Content-Length: '.$size);

    $i = 0;
    while($i<=$size){
        //Output the chunk
        get_chunk($file,(($i==0)?$i:$i+1),((($i+$chunks)>$size)?$size:$i+$chunks));
        $i = ($i+$chunks);
    }

}

//Callback function for CURLOPT_WRITEFUNCTION, This is what prints the chunk
function chunk($ch, $str) {
    print($str);
    return strlen($str);
}

//Function to get a range of bytes from the remote file
function get_chunk($file,$start,$end){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $file);
    curl_setopt($ch, CURLOPT_RANGE, $start.'-'.$end);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'chunk');
    $result = curl_exec($ch);
    curl_close($ch);
}

//Get total size of file
function get_size($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    return intval($size);
}
?>
 16 февр. 2014 г., 00:03
@madman открой новый вопрос, с твоим кодом, который ты попробовал.
 15 февр. 2014 г., 23:27
есть ли шанс добавить http_auth? я сделал это, и теперь мой керл не работает curl_setopt ($ ch, CURLOPT_USERPWD, 'u: p'); curl_setopt ($ ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
 12 июн. 2012 г., 10:51
readfile работает с потоками PHP, например Вы можете заставить его получать удаленные файлы. Потоковое копирование Потоковое копирование также может быть чем-то, на что стоит обратить внимание, если это возможно для прямой трансляции на выход PHP (что, я думаю, возможно). Однако я думаю, что readfile все еще немного легче.php.net/manual/en/book.stream.php ; php.net/manual/en/stream.contexts.php и наконец:ua2.php.net/manual/en/function.readfile.php
 12 июн. 2012 г., 10:45
Мы говорили об удаленном файле, я хотел бы видеть пример того, что вы имеете в виду, когда я пытался разобраться с этим вопросом в течение часа. :)
 12 июн. 2012 г., 10:38
Для лучшей производительности рассмотрите возможность использованияreadfile и контексты потока PHP в будущем. Тебе понравится это.

Ваш ответ на вопрос