Symfony:导出(CSV)文件有限制吗?
Symfony: Export (CSV) File has limit?
我正在尝试使用 Symfony 5 发送生成的 CSV 文件,但似乎已达到我无法克服的极限。
出于测试原因,我将其分解为基础中的基础;所以我发送静态数据,生成一个 txt-file 并且不做任何逻辑。在我下面的示例代码中,如果我进行 65 次迭代,则会生成文件并将其作为下载发送到浏览器(即 4KB)。如果我执行 66 或将单个字母添加到 $data 示例数据字符串,它将全部显示在浏览器中 window。
即使经过 1000 次迭代,完全相同的代码在 Symfony 之外也能完美运行。我也没有从 dev.log 中得到任何可能有帮助的错误或任何内容。
public function saveCSV(Request $request, DelcampeParser $parser) {
$response = new Response();
// same with
// $response = new StreamedResponse();
// $response->setCallback(function(){});
$response->headers->set('Content-Type', 'text/plain; charset=utf-8');
$disposition = HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
'foo.txt'
);
$response->headers->set('Content-Disposition', $disposition);
$data = array(0 => 'abcdefghijklmnopqrstuvwxyz');
for ($a=1;$a<=66;$a++) {
var_dump($data);
}
return $response;
}
怎么了?为什么我无法在 Symfony 中生成更大的文件?
谢谢。
[编辑]
我有一个新的理论:PHP 的输出缓冲设置为 4KB。每当缓冲区已满时,缓冲数据就会发送到浏览器。不幸的是,这发生在 Symfony 发送 headers 之前,因此生成了浏览器输出。我怎样才能改变这种行为?
我现在有了一个有效的 StreamedResponse 答案,希望它也能满足 Symfony 的所有要求和建议:
// in the Controller
public function saveCSV(Request $request, Parser $parser) {
$response = new StreamedResponse();
$data = $request->get("sd"); // sd comes out of a form that posts a multidimensional array
$response->setCallback(function() use ($data, $parser) {
$parser->generateCSV($data);
});
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$disposition = HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
"delcampeimport_".date("Ymd-Hi").".csv",
);
$response->headers->set('Content-Disposition', $disposition);
return $response;
}
和我的服务
public function generateCSV($dataarray) {
$out = fopen('php://output', 'w+');
// send header rows of csv file
fputs($out, "website_visibility,category_id,title, /* ..., */ images\r\n");
// generate data
foreach($dataarray AS $stamp) {
$stampdata = array (
'a' => 'CH',
'b' => $stamp['category'],
'c' => htmlentities($stamp['title']),
// ...
'aa' => $stamp['img1'].
($stamp['img2'] ? ";".$stamp['img2']:"").
($stamp['img3'] ? ";".$stamp['img3']:"")
);
// send csv data
fputcsv($out, $stampdata);
}
fclose($out);
}
感谢您的投入
我正在尝试使用 Symfony 5 发送生成的 CSV 文件,但似乎已达到我无法克服的极限。 出于测试原因,我将其分解为基础中的基础;所以我发送静态数据,生成一个 txt-file 并且不做任何逻辑。在我下面的示例代码中,如果我进行 65 次迭代,则会生成文件并将其作为下载发送到浏览器(即 4KB)。如果我执行 66 或将单个字母添加到 $data 示例数据字符串,它将全部显示在浏览器中 window。 即使经过 1000 次迭代,完全相同的代码在 Symfony 之外也能完美运行。我也没有从 dev.log 中得到任何可能有帮助的错误或任何内容。
public function saveCSV(Request $request, DelcampeParser $parser) {
$response = new Response();
// same with
// $response = new StreamedResponse();
// $response->setCallback(function(){});
$response->headers->set('Content-Type', 'text/plain; charset=utf-8');
$disposition = HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
'foo.txt'
);
$response->headers->set('Content-Disposition', $disposition);
$data = array(0 => 'abcdefghijklmnopqrstuvwxyz');
for ($a=1;$a<=66;$a++) {
var_dump($data);
}
return $response;
}
怎么了?为什么我无法在 Symfony 中生成更大的文件?
谢谢。
[编辑] 我有一个新的理论:PHP 的输出缓冲设置为 4KB。每当缓冲区已满时,缓冲数据就会发送到浏览器。不幸的是,这发生在 Symfony 发送 headers 之前,因此生成了浏览器输出。我怎样才能改变这种行为?
我现在有了一个有效的 StreamedResponse 答案,希望它也能满足 Symfony 的所有要求和建议:
// in the Controller
public function saveCSV(Request $request, Parser $parser) {
$response = new StreamedResponse();
$data = $request->get("sd"); // sd comes out of a form that posts a multidimensional array
$response->setCallback(function() use ($data, $parser) {
$parser->generateCSV($data);
});
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$disposition = HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
"delcampeimport_".date("Ymd-Hi").".csv",
);
$response->headers->set('Content-Disposition', $disposition);
return $response;
}
和我的服务
public function generateCSV($dataarray) {
$out = fopen('php://output', 'w+');
// send header rows of csv file
fputs($out, "website_visibility,category_id,title, /* ..., */ images\r\n");
// generate data
foreach($dataarray AS $stamp) {
$stampdata = array (
'a' => 'CH',
'b' => $stamp['category'],
'c' => htmlentities($stamp['title']),
// ...
'aa' => $stamp['img1'].
($stamp['img2'] ? ";".$stamp['img2']:"").
($stamp['img3'] ? ";".$stamp['img3']:"")
);
// send csv data
fputcsv($out, $stampdata);
}
fclose($out);
}
感谢您的投入