Php CSV文件生成错误

Php CSV文件生成错误,php,mysql,wordpress,csv,Php,Mysql,Wordpress,Csv,我正在为一个客户端做一个项目——一个wordpress插件,它创建并维护一个组织成员数据库。我要注意的是,这个插件在wordpress数据库中创建了一个新表(而不是将数据作为自定义类型的元数据处理)。我已经对插件做了很多修改,但是我有一个功能问题(我没有改变) 此功能的一半用于csv导入和插入,效果非常好。此序列的另一半是一项功能,可将此表的内容作为csv下载。这部分在我的本地系统上运行良好,但在服务器上运行时失败。我把剧本的每一部分都讲了一遍,似乎一切都讲得通。坦率地说,我不知道为什么它会失败

我正在为一个客户端做一个项目——一个wordpress插件,它创建并维护一个组织成员数据库。我要注意的是,这个插件在wordpress数据库中创建了一个新表(而不是将数据作为自定义类型的元数据处理)。我已经对插件做了很多修改,但是我有一个功能问题(我没有改变)

此功能的一半用于csv导入和插入,效果非常好。此序列的另一半是一项功能,可将此表的内容作为csv下载。这部分在我的本地系统上运行良好,但在服务器上运行时失败。我把剧本的每一部分都讲了一遍,似乎一切都讲得通。坦率地说,我不知道为什么它会失败

包含该逻辑的php文件仅链接到。文件:

<?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
}