У меня проблема с моей веб-страницей. Я создаю инструмент отчета для загрузки данных в формате .csv. У меня есть php-скрипт, который собирает данные и создает из них csv. Скрипт вызывается командой exec(), подробный код ниже. Сам скрипт использует file_put_contents() для создания файла, который затем сохраняется в моей папке /tmp/ до его загрузки (я работаю в докеризованной среде, и наши правила фильтрации удаляют файл при следующем запросе, но я мог бы хранить файл постоянно где-нибудь еще, если это будет необходимо). Затем я проверяю наличие файла с помощью file_exists() и продолжаю вызывать функцию загрузки. В Firefox я получаю желаемый результат, файл с правильным содержимым только данных csv.
Моя основная проблема: Когда я загружаю csv в Chrome, я получаю данные csv, за которыми следует html-источник моей страницы, поэтому начиная с <!doctype html> в первой строке после данных csv, затем с <html lang = "de"> в следующей строке te csv и так далее.
Позвольте мне показать вам код:
В моем скрипте:
private function writeToFile($csv)
{
$fileName = '/path/to/file' '.csv';
echo "\n" . 'Write file to ' . $fileName . "\n";
file_put_contents($fileName, $csv);
}
В моем классе страницы:
$filePath = '/path/to/finished/csv/'
exec('php ' . $skriptPath . $skriptParams);
if (file_exists($filePath)) {
$this->downloadCsv($filePath);
} else {
$pageModel->addMessage(
new ErrorMessage('Error Text')
);
}
Моя функция загрузки в том же классе:
private function downloadCsv($filePath)
{
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename = "' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
}
Показанное выше работает в Firefox, но не в Chrome. Я уже пытался очистить выходной буфер с помощью ob_clean() или отправить и отключить его с помощью ob_end_flush(), но для Chrome ничего не получилось.
Я также пробовал что-то подобное в моей функции загрузки:
header('Content-Disposition: attachment; filename = "' . basename($filePath) . '"');
$fp =fopen($filePath, 'rw');
fpassthru($fp);
fclose($fp);
Это дает одинаковые результаты в Firefox и Chrome - я получаю данные csv, за которыми следует исходный код html, смешанный в один и тот же файл.
Я работаю в среде Symfony, если это может быть из справки, я видел, что есть некоторые вспомогательные функции для загрузки файлов, но я до сих пор не мог их успешно использовать.
До сих пор моя цель состояла только в том, чтобы заставить загрузку работать в Chrome, чтобы иметь работающий mvp, который можно запустить в производство - предполагается, что он предназначен только для внутреннего использования, поэтому мне не нужно заботиться об IE или какой-либо другой мерзости, потому что наши Персоналу говорят использовать нормальный браузер... Но если кто-то увидит недостатки в общей концепции, не стесняйтесь говорить мне!
Заранее спасибо :)






Итак, мне удалось заставить его работать, я был на неправильном пути с выходным буфером, но простого exit() после моего readfile() было достаточно, чтобы части html не попали в файл csv.
Код:
private function downloadCsv($filePath)
{
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename = "' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit;
}