fwrite () и UTF8 - PullRequest
       66

fwrite () и UTF8

9 голосов
/ 14 июня 2011

Я создаю файл, используя php fwrite (), и я знаю, что все мои данные находятся в UTF8 (я провел обширное тестирование по этому вопросу - при сохранении данных в БД и выводе на обычную веб-страницу все работает нормально и сообщает как utf8.) , но мне говорят, что файл, который я выводю, содержит данные, отличные от utf8 :( В bash (CentOS) есть команда для проверки формата файла?

При использовании vim содержимое отображается как:

Donâ ~ @ ~ Да делай что угодно .... Это ~ @ ~ Да отличный сайт с все .... Мы просто @ Yve только запущен /

Буду признателен за любую помощь: либо подтверждение того, что файл является UTF8, либо как записать в файл содержимое utf8.

UPDATE

Чтобы уточнить, откуда я знаю, что у меня есть данные в UTF8, я сделал следующее:

  1. БД имеет значение utf8 При сохранении данных
  2. к базе данных, я запускаю это сначала:

    $enc = mb_detect_encoding($data);

    $data = mb_convert_encoding($data, "UTF-8", $enc);

  3. Непосредственно перед запуском fwrite я проверил данные с помощью Обратите внимание, что каждый фрагмент данных возвращает 'IS utf-8'

    if (strlen($data)==mb_strlen($data, 'UTF-8')) print 'NOT UTF-8'; else print 'IS utf-8';

Спасибо!

Ответы [ 8 ]

26 голосов
/ 31 августа 2012

Если вы знаете, что данные в формате UTF8, то вы хотите настроить заголовок.

Я написал решение, отвечающее на другой шаг.

Решение состоит в следующем: поскольку метка порядка байтов UTF-8 равна \xef\xbb\xbf, мы должны добавить ее в заголовок документа.

<?php
function writeStringToFile($file, $string){
    $f=fopen($file, "wb");
    $file="\xEF\xBB\xBF".$file; // this is what makes the magic
    fputs($f, $string);
    fclose($f);
}
?>

Вы можете адаптировать его к своему коду, в основном вы просто хотите убедиться, что вы пишете файл UTF8 (как вы сказали, вы знаете, что ваш контент в кодировке UTF8).

6 голосов
/ 14 июня 2011

fwrite() не является бинарно-безопасным. Это означает, что ваши данные - будь они правильно закодированы или нет - могут быть искажены этой командой или ее подпрограммами.

Чтобы быть в безопасности, вы должны использовать fopen() с флагом двоичного режима. это b. После этого fwrite() сохранит ваши строковые данные «как есть», то есть в PHP до сих пор двоичные данные, потому что строки в PHP - это двоичные строки.

Справочная информация: Некоторые системы отличаются между текстовыми и двоичными данными. Бинарный флаг будет явно указывать PHP в таких системах использовать двоичный вывод. Когда вы имеете дело с UTF-8, вы должны позаботиться о том, чтобы данные не обрабатывались. Это предотвращается обработкой строковых данных как двоичных данных.

Однако: Если это не так, как вы сказали в своем вопросе, что кодировка данных в кодировке UTF-8 сохранена, то ваша кодировка будет нарушена, и даже двоичная безопасная обработка сохранит нарушенный статус. Тем не менее, с двоичным флагом вы по-прежнему гарантируете, что это не та часть вашего приложения, которая нарушает работу fwrite().

В другом ответе по праву написано, что вы не знаете кодировку, если у вас есть только данные. Тем не менее, вы можете проверить данные, если они проверяют кодировку UTF-8 или нет, поэтому у вас есть хоть какой-то шанс проверить кодировку. Функция в PHP, которая делает это, я опубликовала в выпущенном вопросе UTF-8, так что она может быть полезна вам, если вам нужно отладить вещи: Ответ: SimpleXML и китайский ищите can_be_valid_utf8_statemachine , это название функции.

2 голосов
/ 14 июня 2011

Проблема в том, что ваши данные имеют двойную кодировку.Я предполагаю, что ваш оригинальный текст выглядит примерно так:

Don’t do anything

с , т. Е. Не прямой апостроф, а правый одиночный кавычка .

Есливы пишете скрипт PHP с этим содержимым и закодированы в UTF-8:

<?php
//File in UTF-8
echo utf8_encode("Don’t"); //this will double encode

Вы получите что-то похожее на ваш вывод.

1 голос
/ 26 января 2016
//add BOM to fix UTF-8 in Excel
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));

Я считаю, что этот кусок работает для меня:)

0 голосов
/ 06 декабря 2018

Попробуйте этот простой способ, который является более полезным, и добавьте его в начало страницы перед тегом <body>:

<head>
  <meta charset="utf-8">
</head>
0 голосов
/ 20 сентября 2018
$handle = fopen($file,"w");
fwrite($handle, pack("CCC",0xef,0xbb,0xbf));
fwrite($handle,$file); 
fclose($handle);
0 голосов
/ 29 июня 2011

Единственное, что мне нужно было сделать, это добавить спецификацию UTF8 в CSV, данные были правильными, но программа чтения файлов (внешнее приложение) не смогла правильно прочитать файл без спецификации

0 голосов
/ 14 июня 2011

I know all my data is in UTF8 - неверно.
Кодировка - это не формат файла.Итак, проверьте кодировку в заголовках страницы, откуда вы берете данные:
header("Content-type: text/html; charset=utf-8;");
и проверьте, действительно ли данные в многобайтовой кодировке:
if (strlen($data)==mb_strlen($data, 'UTF-8')) print 'not UTF-8';<br> else print 'utf-8';

...