Php SQL->;CSV(utf8 BOM表标题无法正常工作)

Php SQL->;CSV(utf8 BOM表标题无法正常工作),php,mysql,csv,Php,Mysql,Csv,我使用下面的代码将MySQL数据导出到.CSV文件中。所有这些都很好,但当我试图导出这些字母ě,š,ř,ž,ý,á,í,é(捷克字母表)时,这些字母ě,ř,č被导出为?。其他字母可以很好地输出 你能帮我解决这个问题吗 <?php /*******EDIT LINES 3-8*******/ $DB_Server = "xxx"; //MySQL Server $DB_Username = "xxx";

我使用下面的代码将MySQL数据导出到.CSV文件中。所有这些都很好,但当我试图导出这些字母
ě,š,ř,ž,ý,á,í,é
(捷克字母表)时,这些字母
ě,ř,č
被导出为
。其他字母可以很好地输出

你能帮我解决这个问题吗

<?php
/*******EDIT LINES 3-8*******/
$DB_Server    = "xxx";                          //MySQL Server    
$DB_Username  = "xxx";                          //MySQL Username     
$DB_Password  = "xxx";                          //MySQL Password     
$DB_DBName    = "xxx";                          //MySQL Database Name  
$DB_TBLName   = "wp_comments";                           //MySQL Table Name
$DB_Query     = "comment_author, comment_content";       //MySQL Query (what to select from db, you can use * for all)
$filename     = "excelfilename";                         //File Name
$filename_columns = array("Autor", "Content");           //File Name of columns
/*******YOU DO NOT NEED TO EDIT ANYTHING BELOW THIS LINE*******/ 

//headers
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Encoding: UTF-8');
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename='.$filename.'.csv;');
header('Content-Transfer-Encoding: binary');  

//create MySQL connection  
mysql_connect($DB_Server,$DB_Username,$DB_Password);
mysql_select_db($DB_DBName);
$sql = "SELECT $DB_Query FROM $DB_TBLName";
$result = mysql_query($sql);

$fh = fopen('php://output', 'w');   
$fp = fwrite($fh, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) )); // Write UTF-8 BOM
if($fp)
{
    fwrite($fh, "sep=\t" . PHP_EOL);   // Hint for MS Excel
    while($row = mysql_fetch_row($result)) {
        fputcsv($fh, $row, "\t");
    }
}
fclose($fh); 

由于没有显式设置,因此将使用编译
libmysql
时使用的默认编码(通常为拉丁1)。在将结果集转换为该字符集的过程中,MySQL将用
替换它无法表示的任何字符

为了避免这种情况,您应该在打开数据库连接后调用,请参阅

这就是说,您真的不应该使用ext/mysql:它现在已经被弃用了,手册中已经包含了关于在新代码中使用ext/mysql的警告将近三年了。考虑或代替。

最后,如果MySQL服务器与PHP在同一台机器上,并且您拥有
文件
权限,为什么不避免将数据全部交给PHP,而只使用MySQL命令生成输出文件呢

//create MySQL connection  
$DB_DSN = "mysql:host=$DB_Server;dbname=$DB_DBName;charset=utf8";
new PDO($DB_DSN, $DB_Username, $DB_Password)->exec("
  SELECT $DB_Query
  INTO OUTFILE '/tmp/$filename.tsv'
  CHARACTER SET utf8
  FROM $DB_TBLName
");

echo "\xef\xbb\xbf"       // Write UTF-8 BOM
   , "sep=\t", PHP_EOL;   // Hint for MS Excel

readfile("/tmp/$filename.tsv");
请注意,您可能需要确保并发进程未使用临时文件


PS:当字段分隔符为逗号字符时,该格式仅称为CSV(“逗号分隔值”);当使用制表符字符作为字段分隔符时,该格式更准确地称为TSV(“制表符分隔值”),并且应具有
.TSV
.tab
扩展名。

由于没有显式设置,因此将使用编译
libmysql
时使用的默认编码(通常为拉丁语1)。在将结果集转换为该字符集的过程中,MySQL将用
替换它无法表示的任何字符

为了避免这种情况,您应该在打开数据库连接后调用,请参阅

这就是说,您真的不应该使用ext/mysql:它现在已经被弃用了,手册中已经包含了关于在新代码中使用ext/mysql的警告将近三年了。考虑或代替。

最后,如果MySQL服务器与PHP在同一台机器上,并且您拥有
文件
权限,为什么不避免将数据全部交给PHP,而只使用MySQL命令生成输出文件呢

//create MySQL connection  
$DB_DSN = "mysql:host=$DB_Server;dbname=$DB_DBName;charset=utf8";
new PDO($DB_DSN, $DB_Username, $DB_Password)->exec("
  SELECT $DB_Query
  INTO OUTFILE '/tmp/$filename.tsv'
  CHARACTER SET utf8
  FROM $DB_TBLName
");

echo "\xef\xbb\xbf"       // Write UTF-8 BOM
   , "sep=\t", PHP_EOL;   // Hint for MS Excel

readfile("/tmp/$filename.tsv");
请注意,您可能需要确保并发进程未使用临时文件


PS:当字段分隔符为逗号字符时,该格式仅称为CSV(“逗号分隔值”);当使用制表符字符作为字段分隔符时,该格式更准确地称为TSV(“制表符分隔值”),并且应具有
.TSV
.tab
扩展名。

虽然不建议使用,但您可以尝试使用“旧方法”通过SQLs设置连接字符集:
设置名称utf8然后
设置字符集utf8选择数据库之后

注意:这两个语句的顺序很重要

编辑#1


我刚刚注意到,在eggyal的回答中,您唯一的问题是缺少
到OUTFILE
的特权。您应该尝试使用eggyal第二段中描述的方法,即在选择数据库后立即使用
mysql\u set\u字符集('utf8')

虽然不建议使用,但您可以尝试使用“旧方法”通过SQLs设置连接字符集:
设置名称utf8然后
设置字符集utf8选择数据库之后

注意:这两个语句的顺序很重要

编辑#1


我刚刚注意到,在eggyal的回答中,您唯一的问题是缺少
到OUTFILE
的特权。您应该尝试使用eggyal第二段中描述的方法,即在选择数据库后立即使用
mysql\u set\u字符集('utf8')

尝试使用此问题中的类将所有字符串转换为utf-8@eggyal是的,我确定,这里有一些截图:并尝试使用这个问题中的类将所有字符串转换为utf-8@eggyal是的,我确定,这里有一些屏幕截图:在我的系统中,我不能将此解决方案
用于OUTFILE
webhosting@pes502:以上答案提供了不止一种解决方案。第二段特别说明了如何修复当前的尝试。在我的示例中,我无法将此解决方案
用于OUTFILE
webhosting@pes502:以上答案提供了不止一种解决方案。第二段特别说明了如何修复当前的尝试。