Я настраиваю новый сервер и хочу полностью поддерживать UTF-8 в своем веб-приложении. Я пробовал это в прошлом на существующих серверах, и мне всегда приходилось возвращаться к другим кодировкам.
Где именно мне нужно установить кодировку? Я знаю, что для этого мне нужно настроить Apache, MySQL и PHP - есть ли какой-нибудь стандартный способ, которому я могу следовать, или, возможно, устранить неполадки, где возникают ошибки?
Ответ 1
Хранение данных:
Укажите utf8mb4 набор символов для всех таблиц и текстовых столбцов в вашей базе данных. Это заставит MySQL физически хранить и извлекать значения, изначально закодированные в UTF-8. Обратите внимание, что MySQL будет неявно использовать utf8mb4 кодировку, если указана utf8mb4_* (без явного набора символов).
В более старых версиях MySQL (<5.5.3) вам, к сожалению, придется использовать простой код utf8, который поддерживает только подмножество символов Unicode.
Доступ к данным:
В коде вашего приложения (например, PHP), в любом методе доступа к БД, который вы используете, вам необходимо установить кодировку соединения на utf8mb4. Таким образом, MySQL не будет выполнять преобразование из собственного UTF-8, когда передает данные вашему приложению, и наоборот.
Некоторые драйверы предоставляют свой собственный механизм для настройки кодировки, который обновляет внутреннее состояние и сообщает MySQL о кодировке, которая будет использоваться при соединении - обычно это предпочтительный подход. В PHP:
Если вы используете уровень абстракции PDO с PHP ≥ 5.3.6, вы можете указать charset в DSN:
$dbh = new PDO('mysql:charset=utf8mb4');
Если вы используете mysqli, вы можете вызвать set_charset():
$mysqli->set_charset('utf8mb4');
mysqli_set_charset($link, 'utf8mb4');
Если вы используете PHP ≥ 5.2.3, вы можете вызвать mysql_set_charset.
Если драйвер не предоставляет свой собственный механизм для установки кодировки, возможно, придется вызвать запрос , чтобы указать MySQL , как ваше приложение использует символы кодировки: SET NAMES 'utf8mb4'.
В отношении utf8mb4/tf8 применяется тот же механизм, который был рассмотрен выше.
При выводе:
Если ваше приложение передает текст в другие программы/системы, они также должны быть проинформированы о кодировке символов. В веб-приложениях браузер должен быть проинформирован о кодировке, в которой представлены данные (через заголовки ответа HTTP или метаданные HTML).
В PHP вы можете использовать параметр default_charset в php.ini или вручную через Content-Type, который создает заголовок MIME самостоятельно, что требует больше работы, но дает тот же эффект.
При кодировании вывода с помощью функции json_encode() добавьте JSON_UNESCAPED_UNICODE в качестве второго параметра.
Входные значения:
К сожалению, вы должны проверять каждую полученную строку как действительную UTF-8, прежде чем пытаться ее сохранить или использовать где-либо. В PHP функция mb_check_encoding() делает свое дело, но вы должны использовать ее постоянно. На самом деле нет никакого способа обойти эту проблему, поскольку недобросовестные клиенты могут отправлять данные в любой кодировке, которой они хотят, и я не нашел способа, избежать этого.
Из того, что известно о текущей спецификации HTML, следующие подпункты не являются обязательными для современного HTML. Насколько я понимаю, браузеры будут работать и отправлять данные в кодировке, указанной для документа. Однако, если вы ориентируетесь на более старые версии HTML (XHTML, HTML4 и т. д.), эти моменты все еще могут быть полезны:
Только для HTML до HTML5 : Если вы хотите, чтобы все данные, отправляемые вам браузерами, были в UTF-8,.то единственным способом надежно сделать это является добавить accept-charset атрибут для всех тегов <form>: <form ... accept-charset="UTF-8">.
Только для HTML до HTML5 : обратите внимание, что в спецификации W3C HTML говорится, что клиенты "должны" по умолчанию отправлять формы обратно на сервер в любой кодировке, которую обслуживает сервер, но это, по-видимому, только рекомендация, следовательно, необходимости в этом нет.
Другие соображения по коду:
Очевидно, что все файлы, которые вы будете использовать (PHP, HTML, JavaScript и т. д.), должны быть закодированы в UTF-8.
Вы должны быть уверены, что каждый раз, когда вы обрабатываете строку UTF-8, вы делаете это безопасно. К сожалению, это самая сложная часть. Наиболее правильный способ сделать это - использовать mbstring расширение PHP .
Встроенные строковые операции PHP по умолчанию не поддерживают UTF-8. Есть некоторые задачи, которые можно безопасно делать с помощью обычных строковых операций PHP (например, конкатенация), но для большинства задач вы должны использовать эквивалентную функцию mbstring.
Чтобы знать, что вы делаете (читай: не испортить), вам действительно нужно знать UTF-8 и то, как он работает на самом низком уровне. Ознакомьтесь с документацией по UTF-8 на любом доступном ресурсе.
Ответ 2
В дополнение к настройке default_charset в php.ini вы можете отправить правильную кодировку, используя header() из вашего кода, перед любым выводом:
header('Content-Type: text/html; charset=utf-8');
Работать с Unicode в PHP легко, если вы понимаете, что большинство строковых функций не работают с Unicode, а некоторые могут полностью искажать строки. PHP считает, что "символы" строки имеют длину 1 байт. Иногда это нормально (например, explode() ищет только последовательность байтов и использует ее в качестве разделителя, поэтому не имеет значения, какие именно символы вы ищете). Но в других случаях, когда функция действительно предназначена для работы с символами, PHP не знает, что в вашем тексте есть многобайтовые символы, которые можно использовать только с Unicode.
Хорошая библиотека для этого - phputf8. Она переопределяет все функции, чтобы вы могли безопасно работать со строками UTF-8. Существуют расширения, такие как mbstring, которые также пытаются сделать это за вас, но я предпочитаю использовать библиотеку, потому что она более портативна. phputf8 в любом случае может использовать mbstring за кулисами для повышения производительности.
Ответ 3
В моем случае я использовал mb_split, который использует регулярное выражение. И для этого мне пришлось вручную убедиться, что кодировка регулярного выражения была utf-8, выполнив mb_regex_encoding('UTF-8');
Также добавлю, что, запустив, mb_internal_encoding(), я обнаружил, что внутренняя кодировка не является utf-8, и мне пришлось исправить это, запустив mb_internal_encoding("UTF-8");.
Ответ 4
Единственное, что можно добавить к предыдущим ответам, - это подчеркнуть, что необходимо обязательно сохранять ваши файлы в кодировке utf-8. Я заметил, что браузеры принимают это свойство, и не устанавливают utf-8 в качестве кодировки кода. Любой приличный текстовый редактор покажет вам это, например, в Notepad ++ есть пункт меню где показывается текущая кодировка и есть возможность изменять ее. Для всех моих файлов php я использую utf-8 по умолчанию.
Некоторое время назад меня попросили добавить поддержку utf-8 в приложение php/mysql, разработанное кем-то другим. Я заметил, что все файлы были закодированы в ANSI, поэтому мне пришлось использовать ICONV для преобразования всех файлов, изменить таблицы базы данных, добавить 'SET NAMES utf-8' в уровень абстракции базы данных. Также пришлось изменить все строковые функции, чтобы использовать эквивалент многобайтовых строковых функций в php.
Web