Php CSV文件生成错误
我正在为一个客户端做一个项目——一个wordpress插件,它创建并维护一个组织成员数据库。我要注意的是,这个插件在wordpress数据库中创建了一个新表(而不是将数据作为自定义类型的元数据处理)。我已经对插件做了很多修改,但是我有一个功能问题(我没有改变) 此功能的一半用于csv导入和插入,效果非常好。此序列的另一半是一项功能,可将此表的内容作为csv下载。这部分在我的本地系统上运行良好,但在服务器上运行时失败。我把剧本的每一部分都讲了一遍,似乎一切都讲得通。坦率地说,我不知道为什么它会失败 包含该逻辑的php文件仅链接到。文件:Php CSV文件生成错误,php,mysql,wordpress,csv,Php,Mysql,Wordpress,Csv,我正在为一个客户端做一个项目——一个wordpress插件,它创建并维护一个组织成员数据库。我要注意的是,这个插件在wordpress数据库中创建了一个新表(而不是将数据作为自定义类型的元数据处理)。我已经对插件做了很多修改,但是我有一个功能问题(我没有改变) 此功能的一半用于csv导入和插入,效果非常好。此序列的另一半是一项功能,可将此表的内容作为csv下载。这部分在我的本地系统上运行良好,但在服务器上运行时失败。我把剧本的每一部分都讲了一遍,似乎一切都讲得通。坦率地说,我不知道为什么它会失败
<?php
// initiate wordpress
include('../../../wp-blog-header.php');
// phpinfo();
function fputcsv4($fh, $arr) {
$csv = "";
while (list($key, $val) = each($arr)) {
$val = str_replace('"', '""', $val);
$csv .= '"'.$val.'",';
}
$csv = substr($csv, 0, -1);
$csv .= "\n";
if (!@fwrite($fh, $csv))
return FALSE;
}
//get member info and column data
$table_name = $wpdb->prefix . "member_db";
$year = date ('Y');
$members = $wpdb->get_results("SELECT * FROM ".$table_name, ARRAY_A);
$columns = $wpdb->get_results("SHOW COLUMNS FROM ".$table_name, ARRAY_A);
// echo 'SQL: '.$sql.', RESULT: '.$result.'<br>';
//output headers
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"members.csv\"");
//open output stream
$output = fopen("php://output",'w');
//output column headings
$data[0] = "ID";
$i = 1;
foreach ($columns as $column){
//DIAG: echo '<pre>'; print_r($column); echo '</pre>';
$field_name = '';
$words = explode("_", $column['Field']);
foreach ($words as $word) $field_name .= $word.' ';
if ( $column['Field'] != 'id' && $column['Field'] != 'date_updated' ) {
$data[$i] = ucwords($field_name);
$i++;
}
}
$data[$i] = "Date Updated";
fputcsv4($output, $data);
//output data
foreach ($members as $member){
// echo '<pre>'; print_r($member); echo '</pre>';
$data[0] = $member['id'];
$i = 1;
foreach ($columns as $column){
//DIAG: echo '<pre>'; print_r($column); echo '</pre>';
if ( $column['Field'] != 'id' && $column['Field'] != 'date_updated' ) {
$data[$i] = $member[$column['Field']];
$i++;
}
}
$data[$i] = $member['date_updated'];
//echo '<pre>'; print_r($data); echo '</pre>';
fputcsv4($output, $data);
}
fclose($output);
?>
但它显然正在被发现,只是失败了。如果我在文件顶部启用phpinfo()
(PHP版本5.2.17),我肯定会得到一个响应-尤其是无法修改头信息(我非常确定,因为phpinfo()
已经生成了头)。但是,所有预期数据都会打印到页面底部(在所有phpinfo诊断之后),因此至少有很多数据工作正常
我猜是有什么东西阻止了fopen
、fwrite
或fclose
功能正常工作(服务器设置?),但我没有足够的经验来确定到底是什么问题
我将再次注意到,这与我的测试环境(localhost/XAMPP、netbeans)中的预期完全一样
任何想法都将不胜感激
更新
好的-今天花了更多的时间。我已经尝试了每个建议的修复,包括@Rudu的writeCSVLine
fix和@Fernando Costa的file\u put\u contents()
建议。事实上,他们都在当地工作。无论是echo
ing,还是fopen
,fwrite
,fclose
例行程序,都很好,没关系
似乎确实存在问题的是在文件开头包含wp blog header.php
,然后是额外的header()
调用。(顺便说一句,服务器上的路径绝对正确。)
如果我注释掉包含
,我会下载一个csv文件,其中植入了一些错误(因为$wpdb
不存在。如果注释掉标题
,我会将所有数据打印到页面上
那么……你知道这里会发生什么吗?
wordpress环境与正确创建文件之间存在一些明显的冲突
学到了很多,但还没有接近答案……我想我可能需要避免wordpress的东西,做一个手动sql查询。好吧,所以我想知道你为什么采用这种方法。它没有什么错,但它所做的就是允许你以与print
和echo
相同的方式写入输出缓冲区使用它,只需使用print或echo:)在流上使用fwrite
可以得到的任何优化都会丢失,方法是通过字符串构建$csv
变量,然后一次性将其写入输出流(优化不是特别必要的)。我的解决方案(与您的原始设计保持一致)是:
现在使用writeCSVLine
代替fputcsv4
遇到同样的问题。偶然发现了这个线程,它做了同样的事情,但是钩住了“plugins_loaded”动作并导出了CSV
尽早导出CSV可以消除标题在访问之前被修改的风险。正如我所指出的,也许我没有完全弄清楚,这是借用的代码-一个公开的wordpress插件,我一直在修改它以满足我对该项目的需要。这个元素一旦加载到服务器上就不起作用了。我一定会尝试你的修改。老实说,开发人员在整个过程中确实做了一些奇怪的事情,我不得不修改,但我没有触及这个特性,因为它在本地工作得很好。谢谢你的回复!谢谢你的帮助,但我还没找到答案。查看我的回复?如果要将文件写入光盘,请尝试使用file_put_contents()而不是fwrite()函数。否则,如果您只想在屏幕上打印内容,请使用print或echo。这对我来说总是很好的。谢谢你的发帖。我从来没有弄明白这一点(有一个草率的黑客在为客户机atm工作)-我会尽快尝试一下。这是一个很难描述的问题。所以我很高兴我第一次偶然发现了这个线索。给了我一些想法,最终让我找到了答案。谢谢
Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.
function escapeCSVcell($val) {
return str_replace('"','""',$val);
//What about new lines in values? Perhaps not relevant to your
// data but they'll mess up your output ;)
}
function writeCSVLine($arr) {
$first=true;
foreach ($arr as $v) {
if (!$first) {echo ",";}
$first=false;
echo "\"".escapeCSVcell($v)."\"";
}
echo "\n"; // May want to use \r\n depending on consuming script
}