Подавлять сообщения с заголовком Content-Disposition в файл вывода

Когда кто-то вызывает URL, я хочу опубликовать его / ее файл .csv. Это работает с заголовками Content-Disposition. Тем не менее, я хотел бы сообщить php в моей программе, когда он должен начинаться с вывода, а когда игнорировать сообщения, выводимые на экран.

Причина в том, что я вызываю общие классы, которые ищут данные в базе данных (CRM). Эти функции поиска должны генерировать какой-либо вывод. Причиной этого является то, что они занимают более 1 минуты (иногда), а вывод напоминает «пинг», указывающий браузерам не закрывать соединение и ждать завершения сценария.
Я не хочу этого вывода в моем CSV-файле, хотя.

<?php
error_reporting(E_ERROR);

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=search.csv');
....
ob_start();

//these two methods can take a long time and they 'ping' between pages
//i.e. after they looked up 450 records, they ping and look up the next 450
$allPublished=OrganizationLookups::lookup(["ORGANISATION_FIELD_4" =>
"true"],$myInsightly);
$allContacts=ContactLookups::lookup(["TAGS" => "TPZ-Mieter"],$myInsightly);
//flush and ob_end_clean was my idea to suppress the output
//but it does not work
flush();ob_flush();
ob_end_clean();

//now i am ready to put everything to the file what comes next
$file = fopen('php://output', 'w');
....
fputcsv($file,$itarray); //in foreach loop
}
fclose($file);
exit();
?>

Как вы можете видеть в коде, я пытаюсь использовать ob_start () и т. Д. Для управления выводом, но он не работает. (Я также попробовал ob_get_clean и т. Д.)
Я также подумал бы, что только материал, записанный в файл $ (php: // output), записывается в файл csv, но он печатает все в него.

-1

Решение

Одним из подходов может быть многочастный ответ, показывающий страницу HTML и обеспечивающий загрузку файла. Однако некоторые браузеры, в частности Chrome, могут столкнуться с проблемами поддержки.

<?php  declare (strict_types=1);
header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');
header('Content-type: multipart/mixed; boundary="MultiPartBoundary"');
?>

--MultiPartBoundary
Content-type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>
<head>
<title>Download</title>
<meta charset="UTF-8">
</head>

<body>
<h1>search.cvs - Download</h1>
<div>
generating CVS
<?php  // fake generation showing progress
for($i=0; $i<10; $i++)
{
sleep(1);
echo '.' . str_repeat(' ', 1024), PHP_EOL;
flush();
}
?>
</div>
</body>
</html>
--MultiPartBoundary
Expires: Sun, 01 Jan 2014 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-type: text/csv; charset=utf-8
Content-Disposition: attachment; filename=search.csv

<?php   // CVS output
echo <<< __EOS__
Col1,Col2,Col3
Val11,Val12,Val13
Val21,Val22,Val23

__EOS__;
?>

--MultiPartBoundary--

я использовал .htaccess отключить буферизацию

<Files "multipart.php">
php_value output_buffering Off
</Files>

альтернативы

Есть более часто используемые подходы, основанные на JavaScript. Принцип всегда один и тот же: вы выполняете исходный запрос, и генерация запускается в фоновом режиме. Последующие запросы, например AJAX или простая перезагрузка, запросите данные с временным идентификатором.

Еще одна более сложная альтернатива — реализовать двунаправленное соединение через веб-сокет с реальной функциональностью сервера.

0

Другие решения

Других решений пока нет …