У моего веб-хоста есть «убийца процессов», который останавливает любой процесс, выполняющийся дольше, чем около 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, но это решение заставило бы меня запретить частичную загрузку для большинства, поскольку у меня была проблема с подсчетом используемой полосы пропускания.