Потоковая передача в файл и браузер
Итак, я ищу что-то более эффективное, чем это:
<?php
ob_start();
include 'test.php';
$content = ob_get_contents();
file_put_contents('test.html', $content);
echo $content;
?>
Проблемы с вышесказанным:
- Клиент ничего не получает, пока вся страница не будет отображаться
- Файл может быть огромным, поэтому я бы предпочел не хранить все это в памяти
Любые предложения?
Ответы
Ответ 1
Интересная проблема; не думаю, что я пытался решить это раньше.
Я думаю, вам понадобится второй запрос, идущий от вашего PHP-интерфейса script на ваш сервер. Это может быть простой вызов http://localhost/test.php. Если вы используете fopen-wrappers, вы можете использовать fread(), чтобы вывести результат test.php по мере его рендеринга и после получения каждого фрагмента вывести его на экран и добавить его в файл test.html.
Вот как это может выглядеть (непроверено!):
<?php
$remote_fp = fopen("http://localhost/test.php", "r");
$local_fp = fopen("test.html", "w");
while ($buf = fread($remote_fp, 1024)) {
echo $buf;
fwrite($local_fp, $buf);
}
fclose($remote_fp);
fclose($local_fp);
?>
Ответ 2
Лучший способ сделать это - использовать первые два параметра, принятые ob_start
: output_callback
и chunk_size
. Первая специфицирует обратный вызов для обработки вывода по мере его буферизации, а последний определяет размер кусков вывода для обработки.
Вот пример:
$output_file = fopen('test.html', 'w');
if ($output_file === false) {
// Handle error
}
$write_ob_to_file = function($buffer) use ($output_file) {
fwrite($output_file, $buffer);
// Output string as-is
return false;
};
ob_start($write_ob_to_file, 4096);
include 'test.php';
ob_end_flush();
fclose($output_file);
В этом примере выходной буфер будет очищен (отправлен) для каждых 4096 байтов вывода (и еще раз в конце вызовом ob_end_flush
). Каждый раз, когда буфер сбрасывается, обратный вызов $write_ob_to_file
вызывается и передается последним фрагментом. Это записывается в test.html. Затем обратный вызов возвращает false
, что означает "вывести этот кусок как есть". Если вы хотите только написать вывод в файл, а не в выходной поток PHP, вы можете вернуть пустую строку.
Ответ 3
Ответ Pix0r - это то, что вам нужно, если вы действительно не нуждаетесь в нем "включено", а не просто выполняете. Например, если у вас есть информация для входа перед test.php, он не будет передаваться в файл, если вы вызываете его с помощью fopen.
Если вам это действительно нужно включить, то то, что у вас есть, является самым простым методом, но если вы хотите иметь постоянный вывод, вам нужно будет фактически написать test.php таким образом, чтобы он выводил, а также сохранял информацию по мере ее поступления, Насколько я знаю, нет никакого способа как собирать буфер, так и выводить его, когда вы идете.
Ответ 4
Здесь вы идете x-send-file, используйте mod_xsendfile, чтобы отправить файл эффективно, очень просто.