在网页上,我使用以下代码将一些数据写入CSV文件,最后以fclose()结束;
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$filename);
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
echo "HELLO WORLD"; // sneaks into CSV!?
为什么" HELLO WORLD"当它已经fclose()时进入CSV下载文件?我想输出要在浏览器中显示的页面的其余HTML。我怎么能这样做?
答案 0 :(得分:5)
1个HTTP请求后跟随1个响应。您无法同时发送内容类型text/csv
和内容类型text/html
(可能是SPDY,但不是纯HTTP)。
fclose
关闭文件描述符,但不关闭浏览器的输出。
您还应该设置Content-Length
标题并输入文件大小。
Mark Baker已经在评论中提出了最重要的观点:
echo
并写信给php://output
会将内容放入同一个信息流:STDOUT
。其他选择是将CSV写入内存(但如果您不使用它则无意义)或文件。详细了解这些流:http://www.php.net/manual/en/features.commandline.io-streams.php
可能的解决方案:
您需要2个HTTP请求。 1对于下载,另一个用于HTML。最流行的方式是首先使用HTML响应并放入类似
的内容<meta http-equiv="refresh"
content="3; URL=http://yourserver.com/download.php?id=pdf&id=123" />
3秒后开始下载。
答案 1 :(得分:4)
(尚未)“CSV文件”。
您正在做的是将数据流发送到客户端,并告诉客户端此流的Content-Type
text/csv
和filename
$filename
。然后,客户端可以选择将其另存为CSV文件,或者只在浏览器中显示。
此代码:
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
有效地执行echo $cvs_cols
会做的事情(用一些额外的东西来格式化csv输出)。
因此,当调用echo "HELLO WORLD";
时,它会在与$cvs_cols
变量的内容相同的数据流中发送。
当您致电fopen('php://output', 'w')
时,您正在为php://output
创建第二个文件句柄,因为默认情况下会创建一个文件句柄以从echo
等调用输出。所以当您调用{{1}时你只关闭第二个文件句柄。
答案 2 :(得分:1)
使用
ob_clean():ob_clean - 清理(擦除)输出缓冲区
flush():flush - 刷新输出缓冲区(flush)
ob_start();
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$filename);
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
ob_end_clean(); // the buffer and never prints or returns anything.
echo "HELLO WORLD"; // sneaks into CSV!?
答案 3 :(得分:0)
这里有一个非常老的线程,但是为了解决这个问题,我只添加了一个简单的exit();。命令。因此,一个按钮使用查询字符串'action = export_csv'调用同一页面,然后使用exit()运行该操作。在最后一行,希望能有所帮助。
<a href="?action=export_csv">Export CSV</a>
然后页面上的“操作”为:
if(isset($_GET['action']) && $_GET['action']=='export_csv'){
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=email-responses.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Email address'));
$db = new PDO('mysql:host=hostname_mysql;dbname=database_mysql;charset=UTF8', username_mysql, password_mysql);
$query = "SELECT XXX FROM XXXX";
$result = $db->query($query);
$data = $result->fetchAll(PDO::FETCH_ASSOC);
// loop over the rows, outputting them
foreach($data as $row){
fputcsv($output, $row);
}
fclose($output);
exit();
}