PHP fread не работает после успешного fopen, write и fclose - PullRequest
3 голосов
/ 01 сентября 2011

Рано утром, и я просто не получаю это:

Следующий код работает, и файл помещается на сервер:

$filename = $ioid . "_" . time();
$fp = fopen("$filename.csv", "w+");
foreach ($csv as $fields) {
    fputcsv($fp, $fields);
}
fclose($fp);

Но это не такработать сразу после (файл 105k):

$fp2 = fopen("$filename.csv", "r");
$output = fread($fp2, 1000000000000);
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=$filename.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $output;
fclose($fp2);

Ничего не читается и ничего не печатается на странице.

Что за очевидное я делаю неправильно?:)

Ответы [ 2 ]

5 голосов
/ 01 сентября 2011

Ваша проблема в том, что fread($fp2, 1000000000000) пытается выделить 1 терабайт большой буфер для чтения файла и явно достигает допустимого предела памяти, если только вы не на 32-битной платформе, где целое число происходит переполнение . В любом случае это не работает.

Если вы хотите прочитать весь файл в выходной буфер и сделать это быстро, используйте readfile() примерно так:

header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=$filename.csv");
readfile("$filename.csv")

Обязательно проверьте журнал ошибок в следующий раз.

Также, если вы не планируете хранить полученные файлы на диске, я рекомендую переделать ваш скрипт, чтобы использовать более безопасный подход:

$fp = tmpfile(); // creates a handle for a temporary file with a unique name
foreach ($csv as $fields) {
    fputcsv($fp, $fields);
}
rewind($fp);
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=report.csv");
fpassthru($fp);
fclose($fp); // this removes the file
1 голос
/ 01 сентября 2011

Проблема в аргументе fread.Ваш код выдает:

Warning: fread() [function.fread]: Length parameter must be greater than 0

при изменении 1000000000000 на 1000, например, это работает.Итак: используйте это так:

$output = file_get_contents("filename.csv");
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=$filename.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $output;
...