Изменить кодировку файла php
Обновлено: 21.11.2024
Чтобы правильно отображать и редактировать файлы, PhpStorm должен знать, какую кодировку использовать. Как правило, файлы исходного кода в основном имеют кодировку UTF-8. Это рекомендуемая кодировка, если у вас нет других требований.
Чтобы определить кодировку файла, PhpStorm использует следующие шаги:
Если присутствует метка порядка байтов (BOM), PhpStorm будет использовать соответствующую кодировку Unicode независимо от всех других настроек. Дополнительные сведения см. в разделе Метка порядка байтов.
Если файл объявляет кодировку явно, PhpStorm будет использовать указанную кодировку. Например, это может относиться к файлам XML или HTML. Явное объявление также переопределяет все остальные настройки, но вы можете изменить его в редакторе.
Если в файле нет спецификации и явного объявления кодировки, PhpStorm будет использовать кодировку, настроенную для файла или каталога в настройках кодировки файла. Если для файла или каталога не настроена кодировка, PhpStorm будет использовать кодировку родительского каталога. Если кодировка родительского каталога также не настроена, PhpStorm будет использовать Project Encoding , а если проекта нет — Global Encoding .
Изменить кодировку, используемую для просмотра файла
Если PhpStorm неправильно отображает символы в файле, возможно, ему не удалось определить кодировку файла. В этом случае вам необходимо указать правильную кодировку для просмотра и редактирования этого файла.
Открыв файл в редакторе, выберите Файл | Свойства файла | Кодировка файла в главном меню или щелкните виджет «Кодировка файла» в строке состояния и выберите правильную кодировку файла.
Список кодировок довольно большой. Вы можете использовать быстрый поиск, чтобы быстро найти правильную кодировку: начните печатать, когда всплывающее окно открыто.
Кодировки, помеченные или могут изменить содержимое файла. В этом случае PhpStorm открывает диалоговое окно, в котором вы можете выбрать, что делать с файлом:
Перезагрузить: загрузить файл в редактор с диска и применить изменения кодировки только к редактору. Вы увидите изменения содержимого, связанные с выбранной кодировкой, но сам файл не изменится.
Преобразовать: перезаписать файл выбранной кодировкой.
Это добавит ассоциацию для файла в настройки кодирования файла. PhpStorm будет использовать указанную кодировку для просмотра и редактирования этого файла.
Настроить кодировку по умолчанию для файлов свойств
PhpStorm применяет системную кодировку по умолчанию к файлам .properties. Чтобы использовать другие кодировки, предоставьте их как escape-последовательности и Unicode. В качестве альтернативы можно определить кодировку по умолчанию для файлов .properties на уровне проекта и использовать другой API, который может читать файлы .properties в указанной вами кодировке.
В диалоговом окне «Настройки/Настройки» ( Ctrl+Alt+S ) выберите «Редактор | Кодировки файлов .
Выполните одно из следующих действий:
Чтобы включить специальный режим, когда символы хранятся в файле свойств как управляющие последовательности, но отображаются как обычные буквы, установите флажок Прозрачное преобразование исходного кода в ASCII . Этот параметр полезен, когда файлы свойств закодированы в ISO 8859-1. Рекомендуется использовать этот подход, если у вас нет особых причин менять кодировку.
В списке Кодировка по умолчанию для файлов свойств выберите кодировку, которая будет использоваться для всех файлов свойств в проекте.
Настройка параметров кодирования файлов
В диалоговом окне «Настройки/Настройки» ( Ctrl+Alt+S ) выберите «Редактор | Кодировки файлов .
PhpStorm использует эти настройки для просмотра и редактирования файлов, для которых не удалось определить кодировку, а также использует указанные кодировки для новых файлов.
Выберите кодировку, которую следует использовать, если другие параметры кодировки неприменимы.
Например, PhpStorm будет использовать эту кодировку для файлов, которые не являются частью какого-либо проекта, или когда вы извлекаете исходный код из системы контроля версий.
Выберите кодировку для файлов, не указанных в таблице.
Укажите путь к файлам или каталогам, для которых вы хотите настроить кодировку.
Выберите кодировку для указанных файлов и каталогов.
Если этот селектор отключен, файл, вероятно, имеет спецификацию или явно указывает кодировку. В этом случае вы не можете настроить кодировку для этого файла.
Кодировка, выбранная для каталога, применяется ко всем файлам и подкаталогам в нем.
Кодировка по умолчанию для файлов свойств
Выберите кодировку для файлов свойств в вашем проекте.
Прозрачное преобразование исходного кода в ASCII
Показывать национальные символы (не определенные в ISO 8859-1) вместо соответствующих escape-последовательностей.
Создать файлы UTF-8
Выберите, как PhpStorm должен создавать файлы UTF-8:
со спецификацией в окне и без спецификации в противном случае
По умолчанию PhpStorm создает файлы UTF-8 без спецификации, поскольку некоторые программы несовместимы со спецификацией, и это может вызвать проблемы при интерпретации скриптов. Однако в некоторых случаях вам может понадобиться иметь спецификацию в файлах UTF-8.
Чтобы добавить или удалить спецификацию из всех файлов UTF-8 в вашем проекте, щелкните правой кнопкой мыши имя своего проекта в окне инструмента "Проект" и выберите "Добавить спецификацию" или "Удалить спецификацию" .
Выберите кодировку вывода консоли
По умолчанию PhpStorm использует системную кодировку для просмотра вывода консоли.
В диалоговом окне «Настройки/Настройки» ( Ctrl+Alt+S ) выберите «Редактор | Общие | Консоль.
Возвращаемые значения
Если установлена кодировка, возвращает true в случае успеха или false в случае неудачи. В этом случае кодировка символов для многобайтового регулярного выражения НЕ изменяется. Если кодировка не указана, возвращается текущее имя кодировки символов.
Журнал изменений
Версия | Описание |
---|---|
8.0.0 | кодировка теперь можно обнулить. |
Примеры
/* Установить внутреннюю кодировку символов в UTF-8 */
mb_internal_encoding ("UTF-8");
/* Показать текущую внутреннюю кодировку символов */
echo mb_internal_encoding ();
?>
См. также
Пользовательские заметки 7 заметок
Особенно при написании PHP-скриптов для использования на разных серверах очень хорошей идеей является явная установка внутренней кодировки где-нибудь поверх каждого обслуживаемого документа, например,
Это, в сочетании с оператором mysql "SET NAMES 'utf8'", избавит от многих проблем с отладкой.
Кроме того, используйте многобайтовые строковые функции вместо тех, к которым вы, возможно, привыкли, например. mb_strlen() вместо strlen() и т. д.
header ('Content-Type: text/html; charset=UTF-8');
Учтите, что строки в ваших исходных файлах должны соответствовать кодировке, указанной вами в mb_internal_encoding. Похоже, синтаксический анализатор загружает необработанные байты из файла и обращается к его внутренней кодировке, чтобы определить их фактическую кодировку.
Чтобы продемонстрировать, следующие выходные данные, как предполагается, когда файл /source/ имеет кодировку Latin-1:
("iso-8859-1");
mb_http_output ("UTF-8");
ob_start ("mb_output_handler");
Теперь типичное использование mb_internal_encoding показано ниже. Внесите изменения в «utf-8», но оставьте кодировку файла /source/ неизменной:
("UTF-8");
mb_http_output ("UTF-8");
ob_start ("mb_output_handler");
В выводе будет показан только тег
без текста.
Сохраните файл в кодировке UTF-8, и тогда результаты будут такими, как ожидалось.
Эта функция преобразует строку string из кодировки ISO-8859-1 в UTF-8 .
Примечание.
Многие веб-страницы, помеченные как использующие кодировку символов ISO-8859-1, на самом деле используют аналогичную кодировку Windows-1252, и веб-браузеры интерпретируют веб-страницы ISO-8859-1 как Windows-1252. . Windows-1252 содержит дополнительные печатные символы, такие как знак евро (€) и фигурные кавычки ( " "), вместо некоторых управляющих символов ISO-8859-1. Эта функция не будет правильно преобразовывать такие символы Windows-1252. Используйте другую функцию, если требуется преобразование Windows-1252.
Параметры
Строка ISO-8859-1.
Возвращаемые значения
Возвращает перевод строки в формате UTF-8 .
Журнал изменений
Версия | Описание |
---|---|
7.2.0 | < td>Эта функция была перенесена в ядро PHP, и, следовательно, снимается требование к расширению XML, чтобы эта функция была доступна.
См. также
- utf8_decode() — преобразует строку с символами ISO-8859-1, закодированными с помощью UTF-8, в однобайтовые символы ISO-8859-1 — выполняет обратное преобразование.
- mb_convert_encoding() — преобразование кодировки символов – преобразование между различными кодировками символов, включая UTF-8, ISO-8859-1 и Windows-1252.
- iconv() – Преобразование строки в запрошенную кодировку – Преобразование между различными кодировками символов.
- recode_string() — перекодировать строку в соответствии с запросом на перекодирование — конвертирует между различными кодировками символов
Примечания, внесенные пользователями 23 примечания
Обратите внимание, что utf8_encode преобразует только строку, закодированную в ISO-8859-1, в UTF-8. Более подходящим названием для него было бы «iso88591_to_utf8». Если ваш текст не закодирован в ISO-8859-1, вам не нужна эта функция. Если ваш текст уже в UTF-8, вам не нужна эта функция. Фактически, применение этой функции к тексту, который не закодирован в ISO-8859-1, скорее всего, просто исказит этот текст.
Если вам нужно преобразовать текст из любой кодировки в любую другую кодировку, используйте iconv().
Вот код, решающий проблему, описанную Стивеном в предыдущем комментарии.
/* Эта структура кодирует разницу между ISO-8859-1 и Windows-1252,
как сопоставление кодировки UTF-8 некоторых управляющих символов ISO-8859-1 с
UTF -8 кодирование неуправляющих символов, которое Windows-1252 помещает
в эквивалентные кодовые точки. */
$cp1252_map = array(
"\xc2\x80" => "\xe2\x82\xac" , /* ЗНАК ЕВРО */
"\xc2\x82" => "\xe2 \x80\x9a" , /* ОДИНАРНАЯ МАЛАЯ-9 КАВАТЫ */
"\xc2\x83" => "\xc6\x92" , /* СТРОЧНАЯ ЛАТИНСКАЯ БУКВА F С КРЮЧКОМ */
" \xc2\x84" => "\xe2\x80\x9e" , /* ДВОЙНАЯ МАЛАЯ-9 КАВАТЫ */
"\xc2\x85" => "\xe2\x80\xa6" , /* ГОРИЗОНТАЛЬНАЯ ЭЛЛИПСИС */
"\xc2\x86" => "\xe2\x80\xa0" , /* КИНЖАЛ */
"\xc2\x87" => "\xe2\x80\xa1" , /* ДВОЙНОЙ КИНЖАЛ */
"\xc2\x88" => "\xcb\x86" , /* БУКВА-МОДИФИКАТОР АКЦЕНТ CIRCUMFLEX */
"\xc2\x89" => "\xe2\x80 \xb0" , /* ПРОМЫШЛЕННЫЙ ЗНАК */
"\xc2\x8a" => "\xc5\xa0" , /* ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА S С КАРОНОМ */
"\xc2\x8b" => "\xe2\x80\xb9" , /* ОДИНОЧНАЯ ЛЕВАЯ ЦИТАТА */
"\xc2\x8c" => "\xc5\x92" , /* ЛАТИНСКАЯ ЗАГЛАВНАЯ ЛИГАТУРА OE */
"\xc2\x8e" => "\xc5\xbd" , /* ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА Z С КАРОНОМ */
"\xc2\x91" => "\xe2\x80\x98" , /* ЛЕВАЯ ОДИНАРНАЯ КАТЫЧКА */
"\xc2\x92" => "\xe2\x80\x99" , /* ПРАВЫЙ SIN GLE QUOTATION MARK */
"\xc2\x93" => "\xe2\x80\x9c" , /* LEFT DOUBLE QUOTATION MARK */
"\xc2\x94" => "\xe2\ x80\x9d" , /* ПРАВАЯ ДВОЙНАЯ КАВАЧКА */
"\xc2\x95" => "\xe2\x80\xa2" , /* ПУЛЯ */
"\xc2\x96" = > "\xe2\x80\x93" , /* БОЛЬШОЕ ТИРЕ */
"\xc2\x97" => "\xe2\x80\x94" , /* БОЛЬШОЕ ТИРЕ */
"\xc2\x98" => "\xcb\x9c" , /* МАЛАЯ ТИЛЬДА */
"\xc2\x99" => "\xe2\x84\xa2" , /* ЗНАК ТОРГОВОЙ МАРКИ */
"\xc2\x9a" => "\xc5\xa1" , /* СТРОЧНАЯ ЛАТИНСКАЯ БУКВА S С КАРОН */
"\xc2\x9b" => "\xe2\x80\xba " , /* ОДИНАРНАЯ ЦИТАТА С ПРАВЫМ УГЛОМ*/
"\xc2\x9c" => "\xc5\x93" , /* ЛАТИНСКАЯ МАЛАЯ ЛИГАТУРА OE */
"\xc2\x9e" = > "\xc5\xbe" , /* СТРОЧНАЯ ЛАТИНСКАЯ БУКВА Z С КАРОНОМ */
"\xc2\x9f" => "\xc5\xb8" /* ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА Y С ДИЭРЕЗИСОМ*/
);
функция cp1252_to_utf8 ( $str ) global $cp1252_map ;
возвратить strtr ( utf8_encode ( $str ), $cp1252_map );
>
Пройтись по вложенным массивам/объектам и закодировать все строки в utf8.
// Использование
class Foo public $somevar = 'whoop whoop' ;
>
$structure = array(
'object' => (object) array(
'entry' => 'hello wörld',
'another_array' => array(
>'string' ,
1234 ,
'другая строка'
)
),
'string' => 'foo' ,
'foo_object' => новый Фу
);
// $structure теперь имеет кодировку utf8
print_r ( $structure );
сбросить($значение);
> else if ( is_object ( $input )) $vars = array_keys ( get_object_vars ( $input ));
foreach ($vars as $var) utf8_encode_deep ($input -> $var);
>
>
>
?>
Если вам нужна функция, которая преобразует массив строк в массив строк в кодировке utf8, эта функция может быть вам полезна:
Моя версия utf8_encode_deep,
Если вам нужна версия, которая возвращает значение без изменения оригинала.
Я много чего перепробовал, но, похоже, это последний способ сохранения при сбое для преобразования любой строки в правильную UTF-8.
функция _convert ( $content ) <
if(! mb_check_encoding ( $content , 'UTF-8' )
ИЛИ !( $content === mb_convert_encoding ( mb_convert_encoding ( $content , 'UTF- 32' , 'UTF-8' ), 'UTF-8' , 'UTF-32' )))
$content = mb_convert_encoding ($content, 'UTF-8');
if ( mb_check_encoding ( $content , 'UTF-8' )) <
// log('Конвертировано в UTF-8');
> else <
// log('Не удалось преобразовать в UTF-8');
>
>
возврат $content ;
>
?>
Для справки, может быть полезно отметить, что:
utf8_encode($s)
фактически идентично:
recode_string('latin1..utf8', $s)< br />и:
icon('iso-8859-1', 'utf-8', $s)
То есть utf8_encode — это особый случай преобразования набора символов.
Если ваша строка, которую нужно преобразовать в utf-8, отличается от iso-8859-1 (например, iso-8859-2 (польский/хорватский)), вы должны использовать recode_string() или iconv() вместо пытаясь разработать сложные операторы str_replace.
Если вы ищете функцию для замены специальных символов значением hex-utf-8 (например, для совместимости с Webservice-Security/WSS4J), вы можете использовать это:
$textstart = "Größe";
$utf8 ='';
$max = strlen($txt);
$utf8 .= $neu;
> // для $i
Но меня это не устраивало, потому что мне нужна была строка в моей кодировке, чтобы сделать некоторые сравнения и другие вещи. Итак, я изменил указанную выше функцию и в сочетании с функцией code2utf(), упомянутой здесь в какой-то другой заметке, мне удалось достичь своей цели:
if ( $iconv_to != "UTF-8" ) $decodedStr = iconv ("UTF-8" , $iconv_to , $decodedStr );
>
$ups = распаковать('C*', $str);
Если (!($aCnt = count($ups))) вернуть истину; // Пустая строка *является* допустимой UTF-8
for ($i = 1; $i 0 && $i 0x9F) return false;
перерыв;
case 0xF0:
if ($cbyte 0x8F) вернуть false;
перерыв;
по умолчанию:
перерыв;
>
$first = false;
>
$tbytes--;
>
если ($tbytes) вернуть false; // неполная последовательность на EOS
>
return true;
>
Если вы еще не догадались: если символ UTF-8 не представлен в кодовой странице ISO-8859-1, символ ? будет возвращен. Возможно, вы захотите обернуть вокруг этого функцию, чтобы убедиться, что вы не сохраняете кучу файлов . в вашу базу данных.
Эта функция может быть полезна при кодировании ключей и значений массива [и сначала проверяет, не находится ли он уже в формате UTF]:
публичная статическая функция to_utf8 ( $in )
<
if ( is_array ( $in )) <
foreach ( $in as $key => $value ) <
$out [to_utf8 ($key)] = to_utf8 ($value);
>
> elseif( is_string ( $in )) <
if( mb_detect_encoding ( $in ) != "UTF-8" )
return utf8_encode ($in );
иначе
возврат $in ;
> else <
возврат $in ;
>
возврат $out ;
>
?>
Надеюсь, это поможет.
Избегайте использования preg_match для определения необходимости utf8_encode:
= $string_input ; // избегайте разрушения
$rc = ($string == "" ? true : false );
?>
/**
* Кодирует смешанную переменную ISO-8859-1 в UTF-8 (совместимость с PHP 4, PHP 5)
* @parammixed $input Массив, ассоциативный или простой
* @param boolean $encode_keys необязательный
* @return смешанный ($input в кодировке utf-8)
*/
функция utf8_encode_mix ($input, $encode_keys = false)
if( is_array ( $input ))
$result = array();
foreach( $input as $k => $v )
<
$key = ( $encode_keys )? utf8_encode ($k): $k;
$result [$key] = utf8_encode_mix ($v, $encode_keys);
>
>
else
$result = utf8_encode ( $input );
>
Я рекомендую использовать эту альтернативу для каждого языка:
Не забудьте установить для всех своих страниц кодировку "utf-8", иначе просто используйте объекты HTML.
Эту функцию я использую для преобразования тайского шрифта (iso-8859-11) в UTF-8. В моем случае он работает правильно. Пожалуйста, попробуйте использовать эту функцию, если у вас возникли проблемы с преобразованием кодировки iso-8859-11 в UTF-8.
if ( ! ereg("[\241-\377]", $string))
return $string;
$iso8859_11 = array(
"\xa1" => "\xe0\xb8\x81",
"\xa2" => "\xe0\xb8\x82",
"\xa3" => "\xe0\xb8\x83",
"\xa4" => "\xe0\xb8\x84",
"\xa5" => "\xe0\xb8\ x85",
"\xa6" => "\xe0\xb8\x86",
"\xa7" => "\xe0\xb8\x87",
"\xa8" = > "\xe0\xb8\x88",
"\xa9" => "\xe0\xb8\x89",
"\xaa" => "\xe0\xb8\x8a",
"\xab" => "\xe0\xb8\x8b",
"\xac" => "\xe0\xb8\x8c",
"\xad" => "\xe0\ xb8\x8d",
"\xae" => "\xe0\xb8\x8e",
"\xaf" => "\xe0\xb8\x8f",
"\xb0 " => "\xe0\xb8\x90",
"\xb1" => "\xe0\xb8\x91",
"\xb2" => "\xe0\xb8\x92",
"\xb3" => "\xe0\xb8\x93",
"\xb4" => "\xe0\xb8\x94",
"\xb5" => "\ xe0\xb8\x95",
"\xb6" => "\xe0\xb8\x96",
"\xb7" => "\xe0\xb8\x97",
" \xb8" => "\xe0\xb8\x98",
"\xb9" => "\xe0\xb8\x99",
"\xba" => "\xe0\xb8\x9a ",
"\xbb" => "\xe0\xb8\x9b",
"\xbc" => "\xe0\xb8\x9c",
"\xbd" => "\xe0\xb8\x9d",
"\xbe" => "\xe0\xb8\x9e",
"\xbf" => "\xe0\xb8\x9f",
"\xc0" => "\xe0\xb8\xa0",
"\xc1" => "\xe0\xb8\xa1",
"\xc2" => "\xe0\xb8\xa2",
>"\xc3" => "\xe0\xb8\xa3",
"\xc4" => "\xe0\xb8\xa4",
"\xc5" => "\xe0\xb8 \xa5",
"\xc6" => "\xe0\xb8\xa6",
"\xc7" => "\xe0\xb8\xa7",
"\xc8" => "\xe0\xb8\xa8",
"\xc9" => "\xe0\xb8\xa9",
"\xca" => "\xe0\xb8\xaa",< br />"\xcb" => "\xe0\xb8\xab",
"\xcc" => "\xe0\xb8\xac",
"\xcd" => "\xe0 \xb8\xad",
"\xce" => "\xe0\xb8\xae",
"\xcf" => "\xe0\xb8\xaf",
"\ xd0" => "\xe0\xb8\xb0",
"\xd1" => "\xe0\xb8\xb1",
"\xd2" => "\xe0\xb8\xb2" ,
"\xd3" => "\xe0\xb8\xb3",
"\xd4" => "\xe0\xb8\xb4",
"\xd5" => " \xe0\xb8\xb5",
"\xd6" => "\xe0\xb8\xb6",
"\xd7" => "\xe0\xb8\xb7",
"\xd8" => "\xe0\xb8\xb8",
"\xd9" => "\xe0\xb8\xb9",
"\xda" => "\xe0\xb8\ xba",
"\xdf" => "\xe0\xb8\xbf",
"\xe0" => "\xe0\xb9\x80",
"\xe1" = > "\xe0\xb9\x81",
"\xe2" => "\xe0\xb9\x82",
"\xe3" => "\xe0\xb9\x83",
"\xe4" => "\xe0\xb 9\x84",
"\xe5" => "\xe0\xb9\x85",
"\xe6" => "\xe0\xb9\x86",
"\xe7 " => "\xe0\xb9\x87",
"\xe8" => "\xe0\xb9\x88",
"\xe9" => "\xe0\xb9\x89",
"\xea" => "\xe0\xb9\x8a",
"\xeb" => "\xe0\xb9\x8b",
"\xec" => "\ xe0\xb9\x8c",
"\xed" => "\xe0\xb9\x8d",
"\xee" => "\xe0\xb9\x8e",
" \xef" => "\xe0\xb9\x8f",
"\xf0" => "\xe0\xb9\x90",
"\xf1" => "\xe0\xb9\x91 ",
"\xf2" => "\xe0\xb9\x92",
"\xf3" => "\xe0\xb9\x93",
"\xf4" => "\xe0\xb9\x94",
"\xf5" => "\xe0\xb9\x95",
"\xf6" => "\xe0\xb9\x96",
"\xf7" => "\xe0\xb9\x97",
"\xf8" => "\xe0\xb9\x98",
"\xf9" => "\xe0\xb9 \x99",
"\xfa" => "\xe0\xb9\x9a",
"\xfb" => "\xe0\xb9\x9b"
);
$string=strtr($string,$iso8859_11);
вернуть $string;
>
ключи для кода юникода
// нужен этот метатег
// обратите внимание, что шрифт sylfean, по-видимому, входит в стандартную комплектацию Windows XP
// Он поддерживает грузинский язык
Повторите предыдущий пост о преобразовании кода GB2312 в код Unicode, в котором отображается следующая функция:
Я обнаружил, что требуется небольшое изменение в коде для правильной обработки латинских символов, встроенных в середину текста gb2312, например, когда текст включает URL-адрес или адрес электронной почты. Просто поменяйте местами две строки в той части оператора, которая обрабатывает ord vals !>127.
В оригинальной функции отбрасывался первый латинский символ, и она не преобразовывала первый нелатинский символ после латинского текста (все было сдвинуто на один символ слишком далеко вправо). Если поменять местами эти две строки, все будет работать правильно во всех примерах, которые я пробовал.
Кроме того, изменился источник файла gb2312.txt, необходимого для этого. Вы можете найти его в нескольких местах:
/*
Каждая функция, показанная до сих пор, является незавершенной или потребляющей ресурсы. Вот два из них: целочисленная последовательность 2 utf (i3u) и последовательность utf для целого числа (u3i). Ниже приведен фрагмент кода, проверяющий поведение скважин на границах диапазона.
Когда-нибудь они могут быть жестко закодированы в PHP.
*/
function u3i($s,$strict=1) < // возвращает целое число для действительной последовательности UTF-8, NULL для пустой, иначе FALSE
// NOT strict: принимает только биты DATA, присутствующие или отсутствующие; strict: проверка длины и битов
if ($s=='') return NULL;
$l=strlen($s); $o=орд($s);
if ($o 6 && $strict) вернуть false;
if ($strict) for ($i=1;$i 0xbf || ord($s) [" . u3i($o) . "]\n";
>
$utf8Str .= $utf8Substring . $ несущность;
>
else $utf8Str .= $subStr;
>
>
Следующее регулярное выражение Perl проверяет правильность формата строки Unicode UTF-8 (разбивается после каждого символа |, так как длинные строки здесь недопустимы. Перед использованием соедините их в одну строку, без пробелов.):< /p>
Как только вы выходите за удобные рамки наборов символов только для английского языка, вы быстро запутываетесь в чудесном причудливом мире UTF-8.Действительно, навигация по проблемам, связанным с UTF-8, может быть разочаровывающей и раздражающей. Этот пост представляет собой краткий рецепт решения этих проблем при работе с PHP и MySQL, в частности, основанный на практическом опыте и извлеченных уроках.
Франсиско – инженер, занимающийся кроссплатформенными приложениями (Ionic/Cordova) и специализирующийся на интеграции аппаратных и программных технологий.
Прочитайте испанскую версию этой статьи, переведенную Мариселой Ордас
Как разработчик MySQL или PHP, как только вы выйдете за удобные рамки наборов символов только для английского языка, вы быстро запутаетесь в чудесном причудливом мире кодировки UTF-8.
Юникод – это широко используемый отраслевой стандарт вычислительной техники, определяющий всестороннее сопоставление уникальных числовых кодовых значений с символами большинства современных письменных наборов символов для обеспечения совместимости систем и обмена данными.
UTF-8 — это кодировка с переменной шириной, которая может представлять каждый символ в наборе символов Unicode. Он был разработан для обеспечения обратной совместимости с ASCII и во избежание осложнений, связанных с порядком следования байтов и метками порядка следования байтов в UTF-16 и UTF-32. UTF-8 стала доминирующей кодировкой символов для World Wide Web, на которую приходится более половины всех веб-страниц.
Например, шестнадцатеричный код Unicode для буквы A — U+0041, который в UTF-8 просто закодирован одним байтом 41. Для сравнения, шестнадцатеричный код Unicode для символа — U+233B4, который в UTF-8 кодируется четырьмя байтами F0 A3 8E B4.
В предыдущем задании мы столкнулись с проблемами кодирования данных при отображении биографий артистов со всего мира. Вскоре выяснилось, что были проблемы с хранимыми данными, так как иногда данные были правильно закодированы, а иногда нет.
Это побудило программистов реализовать множество исправлений, иногда с помощью JavaScript, иногда с метатегами кодировки HTML, иногда с PHP и т. д. Вскоре мы получили список из 600 000 биографий артистов с двойной или тройной кодировкой информации, причем данные хранятся по-разному в зависимости от того, кто запрограммировал эту функцию или внедрил патч. Классическое техническое крысиное гнездо.
Действительно, навигация по проблемам с кодировкой данных UTF-8 может быть разочаровывающей и раздражающей. Этот пост представляет собой краткую кулинарную книгу для решения этих проблем с UTF-8 при работе с PHP и MySQL, в частности, основанную на практическом опыте и извлеченных уроках (и частично благодаря информации, обнаруженной здесь и здесь). р>
В частности, в этом посте мы рассмотрим следующее:
- Модификации, которые необходимо внести в файл php.ini и код PHP.
- Модификации, которые вам нужно внести в файл my.ini, и другие проблемы, связанные с MySQL, о которых следует знать (включая модификации конфигурации, необходимые, если вы используете Sphinx)
- Как перенести данные из базы данных MySQL, ранее закодированной в latin1, чтобы вместо этого использовать кодировку UTF-8
Кодировка PHP UTF-8 — изменения в файле php.ini:
Первое, что вам нужно сделать, это изменить файл php.ini, чтобы использовать UTF-8 в качестве набора символов по умолчанию:
(Примечание: впоследствии вы можете использовать phpinfo(), чтобы убедиться, что это установлено правильно.)
Хорошо, круто, теперь PHP и UTF-8 должны отлично работать вместе. Верно?
Ну, не совсем так. На самом деле, даже не близко.
Хотя это изменение гарантирует, что PHP всегда выводит UTF-8 в качестве кодировки символов (в заголовках Content-type ответа браузера), вам все же необходимо внести ряд изменений в код PHP, чтобы убедиться, что он правильно обрабатывает и генерирует символы UTF-8.
Кодировка PHP UTF-8 — изменения в вашем коде:
Чтобы убедиться, что ваш код PHP хорошо работает в изолированной программной среде кодирования данных UTF-8, вам необходимо сделать следующее:
Установите UTF-8 в качестве набора символов для всех заголовков, выводимых вашим кодом PHP
В каждом выходном заголовке PHP укажите кодировку UTF-8:
Укажите UTF-8 в качестве типа кодировки для XML
Удалить из XML неподдерживаемые символы
Поскольку не все символы UTF-8 допускаются в XML-документе, вам необходимо удалить такие символы из любого XML-файла, который вы создаете. Полезной функцией для этого (которую я нашел здесь) является следующая:
Как разработчики, наш мир состоит из текста, но компьютеры понимают только числа. Что дает? Процесс, называемый кодированием символов, преобразует числа в буквы. Достаточно просто, пока вы не поймете, что нам нужно кодировать каждый символ из каждого языка, сохраняя при этом небольшие размеры файлов и сохраняя совместимость с устаревшими системами. В этой статье Хосе показывает нам все, что нам нужно знать о кодировке символов для PHP-разработчиков, включая то, что делать, когда она ломается!
Ваш PHP-проект, вероятно, связан с большим количеством данных, поступающих из разных мест, таких как база данных или API, и каждый раз, когда вам нужно их обработать, вы можете столкнуться с проблемой кодирования.
Эта статья поможет вам подготовиться к тому, когда это произойдет, и лучше понять, что происходит за кулисами.
Введение в кодирование
Кодирование лежит в основе любого языка программирования, и обычно мы воспринимаем его как должное. Все работает до тех пор, пока не перестанет работать, и мы получим некрасивую ошибку, например, "Неправильно сформированные символы UTF-8, возможно, неправильно закодированные".
Чтобы выяснить, почему что-то в кодировке может не работать, сначала нужно понять, что мы подразумеваем под кодировкой и как она работает.
Код Морзе
Азбука Морзе — отличный способ объяснить, что такое кодировка. Когда он был разработан, это был один из первых случаев в истории, когда сообщение могло быть закодировано, отправлено, а затем декодировано и понято получателем.
Если бы мы использовали азбуку Морзе для передачи сообщения, нам сначала нужно было бы преобразовать наше сообщение в точки и тире (также называемые короткими и длинными знаками) — единственные два сигнала, доступные в этом методе. Как только сообщение достигает адресата, получатель должен преобразовать его из азбуки Морзе в английский язык. Это выглядит примерно так:
Эта система была изобретена примерно в 1837 году, и люди вручную кодировали и расшифровывали сообщения. Например,
- S кодируется как . (три коротких отметки)
- T as – (один длинный знак)
- U as ..- (две короткие отметки и одна длинная отметка)
Вот кодировка радиста азбукой Морзе:
На "Титанике" азбука Морзе использовалась для отправки и получения сообщений, включая последнее, где просили о помощи ("CQD" — это сигнал бедствия).
При компьютерном кодировании компьютеры кодируют и декодируют символы очень похожим образом. Разница лишь в том, что вместо точек и тире у нас в двоичном коде единицы и нули.
Двоичные и символы
Как вы, наверное, знаете, компьютеры понимают двоичный код только из единиц и нулей, поэтому символа не существует. Оно интерпретируется используемым вами программным обеспечением.
Чтобы кодировать и декодировать символы в 1 и 0, нам нужен стандартный способ сделать это, чтобы, если я отправлю вам кучу 1 и 0, вы интерпретировали (декодировали) их так же, как я кодировал их.
Представьте, что произошло бы, если бы каждый компьютер по-своему переводил двоичный код в символы и наоборот. Если вы отправили сообщение другу, он не смог увидеть ваше настоящее сообщение, потому что для его компьютера ваши 1 и 0 означали бы что-то другое. Вот почему нам нужно договориться о том, как мы преобразуем символы в двоичный код и наоборот; нам нужен стандарт.
Стандарты
У стандартов кодирования долгая история. Нам не нужно полностью изучать историю здесь, но важно знать две важные вехи, которые определили, как компьютеры могут использовать кодирование, особенно с появлением Интернета.
ASCII
ASCII, разработанный в 1963 году, является одним из первых и наиболее важных стандартов и используется до сих пор (мы объясним это позже). ASCII означает американский стандартный код для обмена информацией. «Американская» часть очень актуальна, поскольку в первой версии она могла кодировать только 127 символов, включая английский алфавит и некоторые основные символы, такие как «?» и ";".
Вот полная таблица:
Компьютеры не могут использовать числа. Как мы уже знаем, компьютеры понимают только двоичный код, 1 и 0, поэтому эти значения затем были закодированы в двоичный код.
Например, "K" равно 75 в ASCII, поэтому мы можем преобразовать его в двоичный код, разделив 75 на 2, и продолжать, пока не получим 0. Если деление неточно, мы добавляем 1 в качестве остатка:
Теперь извлекаем «остатки» и вставляем их в обратном порядке:
Итак, в ASCII буква "К" закодирована как 1001011 в двоичном формате.
Основная проблема с ASCII заключалась в том, что он не охватывал другие языки. Если вы хотели использовать свой компьютер на русском или японском языке, вам нужен был другой стандарт кодировки, который не был бы совместим с ASCII.
Вы когда-нибудь видели в своем тексте такие символы, как "." или "Ã,ÂÂÂÂÂ"? Они вызваны проблемой кодирования. Программа пытается интерпретировать символы с использованием одного метода кодирования, но они не представляют ничего значимого, поскольку были созданы с использованием другого метода кодирования. Вот почему нам понадобился наш второй большой прорыв, Unicode и UTF-8.
Юникод
Целью разработки Unicode было найти уникальный способ преобразования любого символа или символа на любом языке в мире в уникальное число, не более того.
Например, "A" равно 65, "Y" – 121, а 🍐 – 127 824.
Проблема в том, что компьютеры могут хранить и обрабатывать только двоичный код, поэтому нам все равно нужно преобразовывать эти числа. Этого можно добиться с помощью различных систем кодирования, но сегодня мы сосредоточимся на самой распространенной: UTF-8.
UTF-8 позволяет использовать стандарт Unicode, предоставляя нам эффективный способ преобразования чисел в двоичный код. Во многих случаях это кодировка по умолчанию для многих языков программирования и веб-сайтов по двум важным причинам:
- UTF-8 (и Unicode) совместимы с ASCII. Когда в 1993 году была создана UTF-8, многие данные были в ASCII, поэтому, сделав UTF-8 совместимой с ней, людям не нужно было преобразовывать данные перед ее использованием. По сути, файл в ASCII можно рассматривать как UTF-8, и это просто работает!
- UTF-8 эффективен. Когда мы храним или отправляем символы через компьютеры, важно, чтобы они не занимали слишком много места. Кому нужен файл размером 1 ГБ, если у вас есть файл размером 256 МБ?
Давайте рассмотрим, как работает UTF-8, и почему он имеет разную длину в зависимости от кодируемого символа.
Насколько эффективна UTF-8?
UTF-8 хранит числа динамически. Первые символы в списке Unicode занимают 1 байт, а последние могут занимать до 4 байтов, поэтому, если вы имеете дело с файлом на английском языке, большинство символов, скорее всего, будут занимать всего 1 байт, как и в ASCII. р>
Это работает, охватывая разные диапазоны спектра Unicode разным количеством байтов.
Например, чтобы закодировать любой символ в исходной таблице ASCII (от 0 до 127 в десятичном виде), нам нужно всего 7 бит, поскольку 2^7 = 128. Следовательно, мы можем хранить все в 1 байте из 8 бит, и у нас еще есть один свободный.
Для следующего диапазона (от 128 до 2047) нам нужно 11 бит, поскольку 2^11 = 2048, что составляет 2 байта в UTF-8, с некоторыми постоянными битами, чтобы дать нам некоторые подсказки. Давайте взглянем на полную таблицу, и вы поймете, что я имею в виду:
При чтении 1 и 0 на компьютере у нас нет концепции пространства между ними, поэтому нам нужен способ сказать: "вот идет такое значение" или "прочитать x бит сейчас". В UTF-8 мы достигаем этого, стратегически размещая несколько единиц и нулей.
Если вы компьютер и читаете что-то, что начинается с 0 в UTF-8, вы знаете, что вам нужно прочитать только 1 байт и отобразить правильный символ из Unicode в диапазоне от 0 до 127.
Давайте рассмотрим пару примеров:
Символ (например, "A") преобразуется в число в соответствии с гигантской таблицей Unicode ("65"). Затем UTF-8 преобразует это число в двоичный код (01000001) в соответствии с показанным шаблоном.
Если у нас есть символ из более высокого диапазона, например смайлик "⚡", который равен 9889 в соответствии с Unicode, нам потребуется 3 байта:
Мы также можем показать, как это работает с PHP просто для развлечения:
Кодирование в PHP
Теперь, когда мы рассмотрели, как работает кодирование в целом, мы можем сосредоточиться на основных частях, которые нам обычно приходится обрабатывать в PHP.
Краткое примечание о версиях PHP
Как вы, наверное, знаете, у PHP уже довольно давно плохая репутация. Однако, к счастью, многие из его первоначальных недостатков были исправлены в более поздних версиях (начиная с 5.X). Поэтому я рекомендую вам использовать самую современную версию, чтобы предотвратить любые непредвиденные проблемы.
Где кодирование имеет значение в PHP
Обычно в программе кодирование имеет значение в трех местах:
- Файлы исходного кода для вашей программы.
- Ввод, который вы получаете.
- Вывод, который вы показываете или сохраняете в базе данных.
Установка правильной кодировки по умолчанию
Поскольку UTF-8 настолько универсальна, рекомендуется установить ее в качестве кодировки по умолчанию для PHP. Эта кодировка установлена по умолчанию, но если кто-то изменил эту настройку, вот как это сделать. Перейдите в файл php.ini и добавьте (или обновите) следующую строку:
Что происходит, когда входящая строка использует другую кодировку? Давайте посмотрим, что делать в этом случае.
Обнаружение кодировки
Когда мы получаем строку при чтении файла, например, или в базе данных, мы не знаем кодировку, поэтому первым шагом является ее обнаружение.
Обнаружение конкретной кодировки не всегда возможно, но у нас есть хорошие шансы с помощью mb_detect_encoding . Чтобы использовать его, нам нужно передать строку, список допустимых кодировок, которые вы ожидаете обнаружить, и хотите ли вы строгое сравнение (рекомендуется в большинстве случаев).
Вот пример того, как определить, находится ли строка в кодировке UTF-8:
Со списком возможных кодировок мы могли бы передать строку или массив:
Эта функция вернет обнаруженную кодировку символов или значение false, если она не может определить кодировку.
Преобразовать в другую кодировку
Как только станет ясно, с какой кодировкой мы имеем дело, следующим шагом будет ее преобразование в нашу кодировку по умолчанию, обычно UTF-8. Теперь это не всегда возможно, так как некоторые кодировки несовместимы, но мы можем попробовать следующий подход:
Если мы хотим автоматически определить кодировку из списка, мы можем использовать следующее:
У нас также есть другая функция в PHP, называемая iconv , но, поскольку она зависит от базовой реализации, использование mb_convert_encoding более надежно и последовательно.
Проверка правильности кодировки
Перед обработкой или сохранением любых входных данных рекомендуется проверить правильность кодировки строки. Для этого мы можем использовать mb_check_encoding, и он вернет true или false. Например, чтобы убедиться, что строка находится в кодировке UTF-8:
Вывод в формате HTML
Поскольку код HTML для веб-сайта очень часто обрабатывается с помощью PHP, вот как мы можем убедиться, что мы установили правильную кодировку для браузера. Мы можем сделать это, просто отправив заголовок перед выводом:
Примечание о базах данных
Базы данных являются важной частью правильной обработки кодирования, поскольку они настроены на использование одной для всех данных, которые у нас есть.
Во многих случаях именно в них мы будем хранить все наши строки и откуда мы будем их считывать, чтобы показать пользователю.
Я рекомендую вам убедиться, что кодировка, которую вы используете для своего проекта, такая же, как и в вашей базе данных, чтобы предотвратить проблемы в будущем.
Настройка кодировки для базы данных зависит от используемой вами системы баз данных, поэтому в этой статье мы не можем описать все способы. Однако имеет смысл обратиться к онлайн-документам и посмотреть, как мы можем это изменить. Например, вот как это сделать с PostgreSQL и MySQL.
Распространенные ошибки PHP, связанные с кодировкой
Неправильно сформированные символы UTF-8, возможно, неправильно закодированные
При преобразовании массива в JSON с помощью json_encode вы можете столкнуться с этой проблемой. Это просто означает, что то, что PHP ожидал получить как UTF-8, не находится в этой кодировке, поэтому мы можем решить проблему, сначала преобразовав ее:
Ошибка кодирования в базе данных
При чтении или записи в базу данных вы можете столкнуться с некоторыми странными символами, такими как следующие:
Эта ошибка обычно указывает на то, что кодировка, которую вы используете для чтения строки, отличается от той, которую использует база данных. Чтобы решить эту проблему, убедитесь, что вы проверяете кодировку строки перед ее сохранением и что вы установили правильную кодировку в своей базе данных.
Заключение
Иногда кодировку сложно понять, но, надеюсь, с этой статьей она станет немного понятнее, и вы почувствуете себя более подготовленным к исправлению любых ошибок, которые могут возникнуть на вашем пути.
Самый важный урок, который следует усвоить, — всегда помнить, что все строки имеют связанную кодировку, поэтому убедитесь, что вы используете правильную кодировку с первого раза, когда сталкиваетесь с ней, и используйте одну и ту же кодировку во всем проекте. включая базу данных и исходные файлы. Если вам нужно выбрать один, выберите современный и распространенный, например UTF-8, так как он хорошо подойдет для любых новых символов, которые могут появиться в будущем, и он очень хорошо разработан.
Honeybadger поддержит вас, когда это необходимо.
Мы являемся единственным средством отслеживания ошибок, объединяющим мониторинг исключений, мониторинг времени безотказной работы и мониторинг cron в единую простую в использовании платформу. Наша миссия: укротить производство и сделать вас лучшим и продуктивным разработчиком.
Хосе М. Хильгадо
Хосе — старший инженер-программист с более чем 10-летним опытом работы. Он работает удаленно в Buffer из Испании и любит хорошие книги и кофе.
"Мы изучили множество систем управления ошибками. Honeybadger на голову выше остальных и каким-то образом становится лучше с каждым новым выпуском».
Майкл Смит
Используете ли вы для мониторинга Bugsnag, Rollbar или Airbrake? Honeybadger включает в себя исключения, время безотказной работы и мониторинг регистрации — и все это, вероятно, дешевле, чем вы платите сейчас. Узнайте, почему так много компаний переходят на Honeybadger, здесь.
Хватит копаться в журналах чата в поисках исправления ошибки, о котором кто-то упоминал в прошлом месяце. Встроенная система отслеживания ошибок Honeybadger делает обсуждение каждой ошибки центральным элементом, поэтому, если она появится снова, вы сможете продолжить с того места, на котором остановились.
Крис Паттон
Читайте также: