Скачать с PHP readfile () работает в Firefox, но не в Chrome - PullRequest
0 голосов
/ 31 января 2019

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

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

1 Ответ

0 голосов
/ 09 февраля 2019

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

}
...