неправильная кодировка в csv, сгенерированном скриптом PHP - PullRequest
0 голосов
/ 05 июля 2011

CSV всегда читается пользователями MAC, поэтому я думаю, что это проблема Mac

Я создаю CSV-файл с этим фрагментом кода (спасибо SO: p)

<?php
include("../include/include.php");
$file_new_export = '../temp/new_hve_full.php';
$query = "select * from mytable";
$result = mysql_query($query) or die("Sql error : " . mysql_error());

if (!$result)
    die('Couldn\'t fetch records');
$i = 0;
while ($row = mysql_fetch_assoc($result)) {

    $hve_biodiv = unserialize($row['hve_a']);
    $hve_ferti = unserialize($row['hve_b']);
    $hve_phyto = unserialize($row['hve_c']);
    $hve_irri = unserialize($row['hve_d']);
    $hve_eco = unserialize($row['hve_e']);

    $content[] = array_merge(array_values($hve_a), array_values($hve_b), array_values($hve_c), array_values($hve_d), array_values($hve_e));
    if ($i == 0)
        $headers = array_merge(array_keys($hve_a), array_keys($hve_b), array_keys($hve_c), array_keys($hve_d), array_keys($hve_e));

    $i++;
}

$fp = fopen($file_new_export, 'w');
if ($fp && $result) {

    fwrite($fp, '<?php ');
    fwrite($fp, 'header(\'Content-Type: application/csv; charset=iso-8859-1\');');
    fwrite($fp, 'header(\'Content-Disposition: attachment; filename="export_hve.csv"\');');
    fwrite($fp, 'header(\'Pragma: no-cache\');');
    fwrite($fp, 'header(\'Expires: 0\');');
    fwrite($fp, '?>');

    fputcsv($fp, $headers, ';');
    foreach ($content as $fields) {
        fputcsv($fp, $fields, ';');
    }
    fclose($fp);
}
?>

Все работает нормально, но я получаю некоторые буквы с неправильной кодировкой, обычно вместо "é" я получаю "È", это близко, но не хорошо ...

Если тип содержимого и имя файла относятся к html или txt файлу, то все символы хорошо отображаются, похоже, это влияет только на файлы csv, если я переключаю кодировку на Excel для Mac на западноевропейскую, то это все еще не работает ...

Не знаю, что здесь делать, я ищу простое решение, не кодирующее все файлы в utf8 или тому подобное, потому что там много данных ... Все в iso8859-1 в соответствии с моими настройками ( Кодировка BDD / IDE / PHP) ...

Спасибо за помощь

Ответы [ 7 ]

8 голосов
/ 05 июля 2011

Ну, я должен думать, что это может решить вашу проблему.Просто поместите эту строку в верхней части вашего php-файла (до включения):

header('Content-Type: text/html; charset=iso-8859-1');

Дополнительная информация по адресу: Заголовок Enconding Type

Это потому, чтоправильно закодируйте файл.

gl, Пауло Буэно

5 голосов
/ 05 июля 2011

.csv - это простой текстовый файл, в котором содержатся структурированные данные.Внутренние части файла не могут указать, какой набор символов использовался.Вы принудительно загружаете файл через «content-disposition: attachment», поэтому заголовок HTTP, указывающий набор символов, будет действовать только на время загрузки.После этого это просто еще один файл на жестком диске.

Если вы собираетесь использовать эти данные исключительно в Excel, я бы предложил использовать PHPExcel для создания реальногоФайл Excel, который не будет иметь эти проблемы перевода.

4 голосов
/ 18 июля 2011

erk, страшно.

В цикле while много грязного, избыточного кода - и вы должны записывать вывод в том же цикле, в котором читаете ввод. И вы ненаписание файла csv - вы пишете файл PHP - что крайне опасно.

include("../include/include.php");
$result = mysql_query("select * from mytable") || die mysql_error();

header('Content-Type: application/csv; charset=iso-8859-1');
header('Content-Disposition: attachment; filename="export_hve.csv"');
while($row = mysql_fetch_assoc($result)) {
  print mkcsv($row) . "\n";
}
exit;
function mkcsv($a)
{
 foreach ($a as $k=>$v) {
   if (!preg_match("/^([0-9.])*$/", $v) {
       $a[$k]="'" . addslashes($v) . "'";
   }
 }
 return implode(',',$a) . "\n";
}

Теперь перейдем к проблеме.

Какой набор символов вы используете в базе данных?Как вы убедились, что кодировка была неправильной?И был неправ из-за того, как вы его извлекли?т.е. вы делали hexdump для данных и проверяли, что 0x233 был преобразован в 0x200?

Попробуйте:

mysql_query('set names latin1');

перед выполнением оператора SELECT.

1 голос
/ 19 июля 2011

UTF8 был создан для обработки большого разнообразия наборов символов, включая французский, испанский, ... языковые наборы. Рекомендуется использовать UTF8.

Тем не менее, в PHP при работе на платформе Mac необходимо использовать функцию iconv () для выполнения преобразований. Например, вы можете сделать следующее:

<?php
$unprocessed_string = "Éléphant";
$processed_spring = iconv('MACINTOSH', 'UTF8', $unprocessed_string);
?>

Не стесняйтесь заменить UTF8 на любой тип кодировки, который вы хотите использовать.

Сложность в том, что вы можете использовать файл, содержащий текст, скопированный из другого программного обеспечения. Я лично заметил, что такой текст уже может быть в UTF8, и в этом случае преобразование не потребуется.

(отредактированный)

Дополнительные примечания:

Это повлияет только на содержимое, управляемое из файла. Если у вас по-прежнему возникают проблемы с отображением содержимого, обязательно используйте функцию header () в PHP, чтобы принудительно задать тип кодировки и кодировку всей страницы.

1 голос
/ 17 июля 2011

Вы, похоже, правильно устанавливаете тип содержимого для вашего файла экспорта через заголовок, но мне любопытно, если проблема не в кодировке вашей базы данных. Если вы храните свои данные в MySQL с другой кодировкой, отличной от iso-8859-1, то это может вызвать некоторые странные проблемы, если вы попытаетесь сохранить / отобразить как таковой.


Немного понюхав вокруг, я обнаружил следующее:

Википедия:
http://en.wikipedia.org/wiki/ISO/IEC_8859-1

Информацию о кодировке символов, обычно ошибочно обозначаемой как "ISO-8859-1", см. Windows-1252.


MySQL:
http://dev.mysql.com/doc/refman/5.0/en/charset-mysql.html
Чтобы выяснить кодировку по умолчанию вашей базы данных, попробуйте выполнить запрос:
SHOW VARIABLES;

Список, который он возвращает, должен иметь переменную с именем

character_set_database 

который из справочника MySQL:

Набор символов, используемый базой данных по умолчанию. Сервер устанавливает эту переменную всякий раз, когда изменяется база данных по умолчанию. Если база данных по умолчанию отсутствует, переменная имеет то же значение, что и character_set_server.

0 голосов
/ 12 декабря 2014

это работает. Наслаждайтесь
просто поместите эту строку перед fputcsv. и он преобразуется в utf8.

foreach ($input_array as $line) {
        $line = array_map("utf8_decode", $line);
        fputcsv($temp_memory, $line, $delimiter);
    }
0 голосов
/ 19 июля 2011

Вы можете попробовать перекодировать его, используя mb_convert_encoding

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...