как добавить данные в БД в любой кодировке? [Дубликат]

В Java, когда оператор «==» используется для сравнения двух объектов, он проверяет, ссылаются ли объекты на одно и то же место в памяти. Другими словами, он проверяет, являются ли имена двух объектов в основном ссылками на одно и то же место в памяти.

Класс Java String фактически переопределяет реализацию equals () по умолчанию в классе Object и переопределяет этот метод, чтобы он проверял только значения строк, а не их местоположения в памяти. Это означает, что если вы вызываете метод equals () для сравнения двух объектов String, то, пока действительная последовательность символов равна, оба объекта считаются равными.

Оператор == проверяет, являются ли две строки точно одним и тем же объектом.

Метод .equals() проверяет, имеют ли две строки одно и то же значение.

1029
задан Machavity 9 January 2018 в 16:49
поделиться

14 ответов

Я хотел бы добавить одну вещь к отличному ответу chazomaticus :

Не забудьте также тег META (например, или HTML4 или XHTML-версия этого файла ):

<meta charset="utf-8">

Это кажется тривиальным, но IE7 дал мне проблемы с этим раньше.

Я делал все правильно; база данных, соединение с базой данных и HTTP-заголовок Content-Type были настроены на UTF-8, и она отлично работала во всех других браузерах, но Internet Explorer по-прежнему настаивал на использовании «западноевропейской» кодировки.

It оказалось, что на странице отсутствует метка META. Добавление этого решения проблемы.

Правка:

У W3C фактически есть довольно большой раздел , посвященный I18N . У них есть ряд статей, связанных с этой проблемой & ndash; описывая HTTP, (X) HTML и CSS сторону вещей:

Они рекомендуют использовать как HTTP-заголовок, так и HTML метатег (или объявление XML в случае XHTML служил XML).

867
ответ дан Community 15 August 2018 в 19:09
поделиться
  • 1
    Я понимаю, что если вы укажете сортировку как utf8_ *, она также автоматически кодируется как utf8. Это неправильно? – chazomaticus 10 November 2008 в 22:49
  • 2
    Я не ошибаюсь: COLLATE означает CHARACTER SET. См. dev.mysql.com/doc/refman/5.0/en/charset-database.html . – chazomaticus 11 November 2008 в 00:01
  • 3
    Нельзя ли также указать кодировку в заголовках HTTP? Вероятно, вам нужен вариант конфигурации для веб-сервера ... – oliver 20 November 2008 в 18:47
  • 4
    @oliver: Да, вы можете отправить его в HTTP-заголовке, но лучше отправить его в контент, потому что, если клиент сохраняет файл, он всегда сохраняет метатег. HTTP-заголовок, скорее всего, просто исчезнет, ​​если браузер не станет достаточно умным, чтобы скопировать его в метатег в сохраненном файле. – user 2 December 2008 в 02:49
  • 5
    Кроме того, убедитесь, что строка является первым дочерним элементом элемента head (перед любым материалом Unicode). Браузер может переинтерпретировать страницу после попадания этого мета-элемента, описанного выше. – alex 20 April 2010 в 09:55
  • 6
    Подумайте о добавлении примеров PDO для установки набора символов. – Ja͢ck 22 October 2012 в 04:35
  • 7
    Обратите внимание: MySQL не говорит на том же языке, что и все остальные. Когда MySQL говорит «utf8», это действительно означает «какой-то странно отсталый вариант UTF-8, который ограничен тремя байтами, потому что бог знает, какая нелепая причина». Если вы действительно хотите UTF-8, вы должны сказать MySQL, что хотите эту странную вещь, которую MySQL любит называть utf8mb4 . Не беспокойтесь об экономии на «WTF!». – R. Martinho Fernandes 9 April 2013 в 10:21
  • 8
    Этот ответ мне очень помог, но я также обнаружил, что в моем случае мне нужно было добавить JSON_UNESCAPED_UNICODE в свой PHP json_encode при передаче результатов запроса базы данных обратно через ajax. – Petay87 14 December 2017 в 10:49
  • 9
  • 10
873
ответ дан Community 5 September 2018 в 18:22
поделиться

В дополнение к настройке default_charset в php.ini вы можете отправить правильную кодировку с помощью header() из вашего кода перед любым выходом:

header('Content-Type: text/html; charset=utf-8');

Работа с Unicode в PHP легко, если вы понимаете, что большинство строковых функций не работают с Unicode, а некоторые могут полностью блокировать строки. PHP считает, что «символы» имеют длину 1 байт. Иногда это нормально (например, explode() ищет только последовательность байтов и использует его как разделитель - так что неважно, какие фактические персонажи вы ищете). Но в других случаях, когда функция фактически предназначена для работы с символами , PHP не знает, что ваш текст имеет многобайтовые символы, которые находятся в Unicode.

Хорошая библиотека для проверки есть phputf8 . Это перезаписывает все «плохие» функции, чтобы вы могли безопасно работать с строками UTF8. Существуют расширения, такие как расширение mbstring, которые тоже пытаются это сделать для вас, но я предпочитаю использовать библиотеку, потому что она более переносимая (но я пишу продукты массового рынка, так что это важно для меня). Но phputf8 может использовать mbstring за кулисами, во всяком случае, для повышения производительности.

55
ответ дан Christopher Nadeau 15 August 2018 в 19:09
поделиться
  • 1
    Задайте настройку перегрузки в php.ini. Это помогает при использовании многобайтовых строк. – Anthony Rutledge 21 December 2015 в 21:52

Поддержка Unicode в PHP по-прежнему огромна. Хотя он способен преобразовывать строку ISO8859 (которая используется внутри нее) в utf8, ей не хватает возможности работать с строками unicode изначально, что означает, что все функции обработки строк будут искажать и повреждать ваши строки. Таким образом, вам нужно либо использовать отдельную библиотеку для правильной поддержки utf8, либо самостоятельно переписать все функции обработки строк.

. Легкая часть - это просто указать кодировку в заголовках HTTP и в базе данных и т. Д., Но нет что имеет значение, если ваш PHP-код не выводит допустимый UTF8. Это сложная часть, и PHP практически не помогает. (Я думаю, что PHP6 должен исправить худшее из этого, но это все еще вдалеке)

6
ответ дан Chuck Burgess 15 August 2018 в 19:09
поделиться

Главный ответ отличный. Вот что я должен был на обычной установке debian / php / mysql:

// storage
// debian. apparently already utf-8

// retrieval
// the mysql database was stored in utf-8, 
// but apparently php was requesting iso. this worked: 
// ***notice "utf8", without dash, this is a mysql encoding***
mysql_set_charset('utf8');

// delivery
// php.ini did not have a default charset, 
// (it was commented out, shared host) and
// no http encoding was specified in the apache headers.
// this made apache send out a utf-8 header
// (and perhaps made php actually send out utf-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// submission
// this worked in all major browsers once apache
// was sending out the utf-8 header. i didnt add
// the accept-charset attribute.

// processing
// changed a few commands in php, like substr,
// to mb_substr

, которая была всем!

5
ответ дан commonpike 15 August 2018 в 19:09
поделиться

Хорошая цель с самого начала - основанная на характере вашего сайта, я нашел много ресурсов по этому поводу в Googling - вы, конечно, не первый в этом разбираетесь.

Предполагается, что у мистического PHP6 все это выпрямилось, правда?

Вы можете в значительной степени установить utf-8 в качестве глобальной кодировки по умолчанию для mysql на уровне сервера, и она по умолчанию будет правильно соответствовать более гранулированных уровней.

7
ответ дан dkretz 15 August 2018 в 19:09
поделиться

Я только что прошел ту же проблему и нашел хорошее решение в руководствах PHP.

Я изменил всю свою кодировку файла на UTF8, а затем по умолчанию на мое соединение. Это решило все проблемы.

if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
   printf("Current character set: %s\n", $mysqli->character_set_name());
}

Просмотреть источник

11
ответ дан Funk Forty Niner 15 August 2018 в 19:09
поделиться
  • 1
    Я потратил час, пытаясь выяснить проблему кодирования на странице, над которой я работаю, и я обычно хорошо разбираюсь в вещах. Я всегда проконсультирую эту страницу, и ваш ответ мне очень помог. Получил мой взнос. В моем случае set_charset('utf8mb4') не работал, но >set_charset("utf8") сделал, и это не было показано в других ответах. – Funk Forty Niner 21 January 2017 в 15:16
  • 2
    @FunkFortyNiner Остерегайтесь: set_charset("utf8") может работать, но будет вести себя по-другому (см. Примечания о различии между utf8 и utf8mb4 и историей версий mysql). Используйте utf8 , если вам нужно И ТОЛЬКО , если вы знаете, что делаете ! – Martin Hennings 24 April 2018 в 10:09

Старая тема, я знаю. Нашел проблему с кем-то, использующим PDO, и ответ заключался в том, чтобы использовать это для строки подключения PDO:

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

Сайт, на котором я взял это, отключен, смог получить его с помощью кеша google.

26
ответ дан iankit 15 August 2018 в 19:09
поделиться
  • 1
    Ищете это немного дальше, это необходимо только для версий PHP до 5.3.6. См. Также: http://stackoverflow.com/a/4361485/2286722 (хотя они используют отдельный $dbh->exec("set names utf8");, я предпочитаю представленный здесь метод). Btw. есть также аналогичная заметка в этом комментарии в руководстве PHP: php.net/manual/en/pdo.construct.php#96325 . – Marten Koetsier 13 August 2015 в 13:55

В моем случае я использовал mb_split, который использует регулярное выражение. Поэтому мне также пришлось вручную убедиться, что кодировка регулярного выражения была utf-8, выполнив mb_regex_encoding('UTF-8');

. В качестве побочной заметки я также обнаружил, запустив mb_internal_encoding(), что внутренняя кодировка не была utf-8 , и я изменил это, выполнив mb_internal_encoding("UTF-8");.

20
ответ дан JDelage 15 August 2018 в 19:09
поделиться

Прежде всего, если вы находитесь в & lt; 5.3PHP, то нет. У тебя много проблем, чтобы справиться.

Я удивлен, что никто не упомянул библиотеку intl , которая имеет хорошую поддержку для unicode, графем, строковых операций, локализации и многих других, см. ниже.

Я приведу некоторую информацию о поддержке Unicode в PHP с помощью слайдов Elizabeth Smith в PHPBenelux'14

INTL

Хорошо:

  • Обертка вокруг библиотеки ICU
  • Стандартизованные локали, установка языка для каждого скрипта
  • Форматирование чисел
  • Форматирование валюты
  • Форматирование сообщений (заменяет gettext)
  • Календари, даты, часовой пояс и время
  • Транслитератор
  • Spoofchecker
  • Пакеты ресурсов
  • Конвертеры
  • Поддержка IDN
  • Graphemes
  • Collation
  • Итераторы

Плохо :

  • Не поддерживает zend_multibite
  • Не поддерживает преобразование входного сигнала HTTP
  • Не поддерживает перегрузку функции

mb_string

  • Включает поддержку zend_multibyte
  • Поддерживает прозрачную кодировку HTTP in / out
  • Предоставляет некоторые обертки для funtionallity, такие как strtoupper

ICONV

  • Первичный для преобразования кодировки
  • Обработчик выходных буферов
  • Функциональность кодирования mime
  • conversion
  • некоторые строковые помощники (len, substr, strpos, strppos)
  • Фильтр потока stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')

БАЗЫ ДАННЫХ

  • mysql: кодировка и сопоставление таблиц и соединений (не сортировка). Также не используйте mysql-msqli или PDO
  • postgresql: pg_set_client_encoding
  • sqlite (3): убедитесь, что он был скомпилирован с поддержкой unicode и intl

Некоторые другие Gotchas

  • Вы не можете использовать имена файлов Unicode с PHP и Windows, если вы не используете расширение третьей части.
  • Отправлять все в ASCII, если вы используете exec, proc_open и другие вызовы командной строки
  • Обычный текст - это не обычный текст, файлы имеют кодировки
  • Вы можете конвертировать файлы «на лету» с фильтром iconv

Я обновлю этот ответ, если что-то изменит добавленные функции и так далее.

19
ответ дан Jimmy Kane 15 August 2018 в 19:09
поделиться
  • 1
    Да, верно. Mysqli и PDO могут использовать свои собственные драйверы. Также они могут использовать драйвер mysqlnd, если вы скомпилируете php с параметрами --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd. – Alexander Yancharuk 16 February 2014 в 19:54

В PHP вам нужно либо использовать функции multibyte , либо включить mbstring.func_overload . Таким образом, такие вещи, как strlen, будут работать, если у вас есть символы, которые принимают более одного байта.

Вам также потребуется определить набор символов ваших ответов. Вы можете использовать AddDefaultCharset, как указано выше, или написать PHP-код, который возвращает заголовок. (Или вы можете добавить тег META в свои HTML-документы.)

8
ответ дан JW. 15 August 2018 в 19:09
поделиться
  • 1
    Большой совет по настройке func_overload - позволяет минимально модифицировать существующий код. – Simon East 15 January 2014 в 06:56
  • 2
    Просто будьте осторожны - какой-то код действительно может полагаться на однобайтовый характер стандартных строковых функций. – JW. 15 January 2014 в 20:18
  • 3
    Важно отметить, что функция mbstring.func_overload устарела с PHP 7.2 из-за проблем, отмеченных в комментарии @ JW выше. Поэтому лучший совет: да, вы должны определенно использовать функции mbstring, но не используйте функцию перегрузки, чтобы стандартные функции работали как многобайтовые. – Simba 7 February 2017 в 14:08

Недавно я обнаружил, что использование strtolower() может вызвать проблемы, когда данные усекаются после специального символа.

Решение заключалось в использовании

mb_strtolower($string, 'UTF-8');

mb_ использует MultiByte. Он поддерживает больше символов, но в целом немного медленнее.

13
ответ дан Martin 15 August 2018 в 19:09
поделиться

Если вы хотите, чтобы сервер MySQL решал набор символов, а не PHP как клиент (старое поведение, предпочтительнее, на мой взгляд), попробуйте добавить skip-character-set-client-handshake к вашему my.cnf в [mysqld] и перезапустить mysql.

Это может вызвать проблемы, если вы используете что-либо, кроме UTF8.

5
ответ дан Nikola Tulimirovic 15 August 2018 в 19:09
поделиться
11
ответ дан Funk Forty Niner 5 September 2018 в 18:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: