Загрузка с PHP readfile() работает в Firefox, но не в Chrome

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

Заранее спасибо :)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
1 146
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, мне удалось заставить его работать, я был на неправильном пути с выходным буфером, но простого 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;

}

Другие вопросы по теме