fpassthru в PHP - PullRequest
       7

fpassthru в PHP

2 голосов
/ 28 февраля 2010

У моего веб-хоста есть «убийца процессов», который останавливает любой процесс, выполняющийся дольше, чем около 5 минут, поэтому мой скрипт загрузки не может работать так долго.

Я подумал, что буду использовать fread-print в течение нескольких секунд, просто чтобы узнать, отменяет ли изначально пользователь загрузку, а затем использовать fpassthru, чтобы выгрузить оставшуюся часть файла.

ob_end_clean();
$file = fopen($this->m_path,'rb'); // read binary
fseek($file, $startByte);
$cnt = 0;
while (!feof($file) && (!connection_aborted()) && ($bytesSent<$bytesToSend) )
{
    $cnt++;
    if($cnt > 25) // to simulate breaking the loop after a certain time has passed
        break;
    set_time_limit(0);
    $buffer = fread($file, 32*1024);
    print($buffer);
    //flush();
    $bytesSent += strlen($buffer);
}
flush(); // has no effect on fpassthru

// --- insert point for the code below --

if(!feof($file))
{
    fpassthru($file);
}
fclose($file);

Проблема в том, что fpassthru поддерживает выполнение скрипта в течение всей загрузки. Я устал использовать буферизацию вывода, что приводит к быстрому завершению работы скрипта, но загрузка прерывается примерно через 8 минут (я отправляю файл размером 30 МБ со скоростью 15 кБ / с).

Одна вещь, которая быстро завершает работу скрипта и позволяет завершить загрузку, это если я вставлю следующее в «точку вставки» выше:

echo("X"); // or pretty much any string literal
flush();

Он работает каждый раз, но файл, конечно, поврежден (как и ожидалось).

Если я вставлю что-то вроде этого:

echo fread($file, 16);
flush();

это не работает (fpassthru не позволяет скрипту завершиться).

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

PHP версия 5.2.11 Apache 2.2.9

EDIT:

Я закончил тем, что заставил свой веб-хостинг увеличить время ожидания до 40 минут, чтобы я мог обслужить файлы с помощью fread-echo и аккуратно выйти со временем, чтобы сэкономить. Я обслуживаю сравнительно небольшие файлы, и возобновление поддерживается для тех немногих посетителей, у которых отключены переводы.

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

1 Ответ

2 голосов
/ 28 февраля 2010

Я вижу два немедленных решения вашей проблемы:

  1. Получить другой хост, который не делает такого рода вещи
  2. Вместо того, чтобы позволять скрипту управлять загрузкой, пусть apache сделает это, просто перенаправит на текущий файл после обновления ваших счетчиков и тому подобного. header('Location: '.$actualFile, true, 303) (303 означает «Просмотреть другие ресурсы», чтобы предотвратить повторную публикацию данных публикации на следующий URL). После этого вы можете просто exit;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...