2014-04-18 119 views
1

我正在使用下面的代码将我的MySQL数据导出到.CSV文件中。所有工作正常,但是当我试图导出这些字母ě, š, č, ř, ž, ý, á, í, é(捷克字母)时,字母ě, ř, č导出为?。其他字母可以正常导出。SQL - > CSV(utf8-BOM头部无法正常工作)

请问您能帮我解决这个问题吗?

<?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); 
+0

尝试使用此问题中的类将所有字符串转换为utf-8。 http://stackoverflow.com/questions/23140358/php-glob-directory-utf8/23140525#23140525 –

+0

不工作在男人:/ – pes502

+0

@eggyal是的我相信,这里有一些截图:[数据库内容](http ://i.imgur.com/zlx2vLc.png)和[导出数据库内容](http://i.imgur.com/zWCit3A.png) – pes502

回答

7

既然你没有明确设置encoding of the database connection,将用于与该libmysql编译默认的编码(通常是LATIN1)。在将结果集转码为该字符集时,MySQL会用?替换它无法表示的任何字符。

为避免这种情况,您应在打开数据库连接—后参见UTF-8 all the way through后调用mysql_set_charset('utf8')。这就是说,你真的不应该使用ext/mysql:它现在已经被弃用了,并且手册已经包含了警告,反对它在近三年的新代码中的使用。改为考虑MySQLiPDO。最后,如果MySQL服务器与PHP在同一台计算机上,并且具有FILE特权,为什么不避免将数据完全交给PHP,并且只需使用MySQL的SELECT ... INTO OUTFILE命令生成输出文件?

//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扩展名。

+0

我无法在我的虚拟主机中使用此解决方案'INTO OUTFILE' – pes502

+0

@ pes502 :上述答案提供的不仅仅是这一种解决方案。第二段特别解释了如何解决当前的问题。 – eggyal

0

虽然PHP documentation不推荐使用,但您可以尝试使用“旧方法”通过SQL设置连接字符集:SET NAMES utf8;,然后SET CHARACTER SET utf8;在您选择数据库之后。

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

编辑#1

我刚刚注意到,在eggyal的回答你唯一的问题是缺乏INTO OUTFILE特权。您应该尝试使用在eggyal的第二段中描述的方法,即在选择数据库之后使用the mysql_set_charset('utf8')