Я использую приведенный ниже код для экспорта данных 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); 
1
pes502 18 Апр 2014 в 15:34

2 ответа

Лучший ответ

Поскольку вы явно не устанавливаете кодировку соединения с базой данных, будет использоваться кодировка по умолчанию, с которой был скомпилирован libmysql (обычно latin1). При перекодировании набора результатов в этот набор символов MySQL заменяет любые символы, которые он не может представить, на ?.

Чтобы этого избежать, вам следует позвонить mysql_set_charset('utf8') < / a> после открытия соединения с базой данных - см. UTF-8 полностью.

Тем не менее, вам действительно не следует использовать ext / mysql вообще: он устарел, и в руководстве содержатся предупреждения против его использования в новом коде в течение почти трех лет. Рассмотрим MySQLi или PDO.

Наконец, если сервер 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.

7
Community 23 Май 2017 в 11:57

Хотя это не рекомендуется в документации PHP, вы можете попробовать используйте "старый способ" для установки набора символов соединения через SQL: SET NAMES utf8;, а затем SET CHARACTER SET utf8; сразу после того, как вы выбрали базу данных.

Примечание: порядок этих двух утверждений имеет значение!

Изменить №1

Я только что заметил, что в ответе eggyal единственная проблема, с которой вы столкнулись, - это отсутствие привилегии INTO OUTFILE. Вам следует попробовать использовать метод, описанный во втором абзаце eggyal, который вместо этого использует the mysql_set_charset('utf8') сразу после выбора вашей базы данных.

0
Gábor Héja 28 Апр 2014 в 14:18