我知道这个错误背后的理论,但它现在又让我发疯了。我在我的应用程序中使用Tonic。使用这个库,您可以将所有流量重定向到您的dispatch.php
脚本,然后执行适当的Resource
并Resource
返回Response
由dispatch.php
.
的输出方法Response
如下:
/**
* Output the response
*/
public function output()
{
foreach ($this->headers as $name => $value) {
header($name.': '.$value, true, $this->responseCode());
}
echo $this->body;
}
所以 AFAIK 这告诉我们你不能在 .php 文件中写任何东西到 php 输出Resource
。
我现在有一个Resource
从输入 csv 动态生成 csv 并将其输出到浏览器(它将 1 列数据转换为不同格式)。
$csv = fopen('php://output', 'w');
// sets header
$response->__set('contentDisposition:', 'attachment; filename="' . $fileName . '"');
while (($line = fgetcsv($filePointer, 0, ",", '"')) !== FALSE) {
// generate line
fputcsv($csv, $line);
}
fclose($filePointer);
return $response;
这可以 100% 正常工作。标题没有问题,并且生成了正确的文件并提供下载。这已经令人困惑了,因为我们在设置标头之前写入输出?fputcsv 实际上做了什么?
我有第二个资源做类似的事情,但它输出自定义文件格式(文本文件)。
$output = fopen('php://output', 'w');
// sets header
$response->__set('contentDisposition:', 'attachment; filename="' . $fileName . '"');
while (($line = fgetcsv($filePointer, 0, ",", '"')) !== FALSE) {
// generate a record (multiple lines) not shown / snipped
fwrite($output, $record);
}
fclose($filePointer);
return $response;
唯一的区别是它使用 fwrite 而不是 fputcsv 和 bang
headers already sent by... // line number = fwrite()
这非常令人困惑!恕我直言,在这两种情况下它实际上都应该失败吗?为什么第一个有效?我怎样才能让第二个工作?(我可以生成一个包含文件的巨大字符串并将其放入响应正文中并且它可以工作。但是文件可能相当大(高达 50 mb),因此希望避免这种情况。)