php не кодирует длинное тире (между прочим корректно);

У меня есть небольшой объект JSON, который я хотел бы отправить на php для размещения в базе данных mySQL. Часть информации в строке представляет собой html-объекты. &emdash доставляет мне проблемы. Он отображается как â€. Есть и другие проблемы с отображением é как é.

Кажется, у меня проблемы с кодировкой. Есть идеи, что может быть не так? Спасибо


person 1252748    schedule 29.08.2012    source источник
comment
Вероятно, набор символов вашей базы данных. Предположительно, для него установлено значение iso-8859-*, и, поскольку данные поступают из JSON, они будут закодированы в юникоде. Измените набор символов базы данных на UTF-8.   -  person DaveRandom    schedule 29.08.2012
comment
@DaveRandom Спасибо! извините за глупость, но это что-то, что я устанавливаю таблицу за таблицей, или базу данных за базой данных, или только для всего моего MySQL?   -  person 1252748    schedule 29.08.2012
comment
Его можно установить для каждой базы данных, для каждой таблицы или даже для каждого столбца. Для этой конкретной задачи вам нужно сделать это только для столбцов, в которых вы храните эти данные, но я бы рекомендовал вам преобразовать всю БД, если это не конфликтует ни с чем другим.   -  person DaveRandom    schedule 29.08.2012
comment
@DaveRandom В разделе «Операции» в PHPMyAdmin я вижу, что для параметра «Сортировка» установлено значение «latin1_swedish_ci». В большом раскрывающемся списке есть вариант для UTF-8. Просто немного запутался, потому что это называется «сопоставление», а не «кодирование»; это то, что я хочу?   -  person 1252748    schedule 29.08.2012
comment
Да, но это не повлияет на существующие столбцы в таблице, это повлияет только на новые, которые вы создаете, и не указываете для них кодировку. Измените его там, а также зайдите в таблицу и отредактируйте все ваши столбцы VARCHAR/CHAR/TEXT.   -  person DaveRandom    schedule 29.08.2012
comment
@DaveRandom Круто. Вы хотите представить это как ответ? Я думаю, это полностью решит мою проблему.   -  person 1252748    schedule 29.08.2012


Ответы (1)


Поскольку данные поступают из JSON, они должны быть закодированы в наборе символов Unicode, по умолчанию используется UTF-8 [Источники: Дуглас Крокфорд, RFC4627].

Это означает, что для того, чтобы сохранить не-ASCII-символ в вашей базе данных, вам нужно либо преобразовать кодировку входящих данных в набор символов вашей базы данных, либо (предпочтительнее) использовать набор символов Unicode для вашей базы данных. Самый распространенный набор символов Unicode — и тот, который я рекомендую вам использовать для этой цели, — это UTF-8.

Вероятно, ваша база данных настроена с использованием одного из наборов латинских символов (ISO-8859-*), и в этом случае вам, скорее всего, просто нужно будет изменить набор символов, используемый для вашей таблицы, и это не нарушит какие-либо из ваших существующих данных — при условии, что в настоящее время у вас нет записей, которые используют какие-либо символы за пределами нижних 128 символов. , Основываясь на ваших комментариях выше, вы должны иметь возможность внести это изменение с помощью phpMyAdmin - вам нужно будет убедиться, что вы изменили каждый существующий столбец, который вы хотите изменить явно, изменение набора символов таблицы/базы данных повлияет только на новые столбцы/ таблицы, созданные без указания набора символов.

Когда вы выводите данные клиенту, вам также нужно сообщить ему, что вы выводите кодировку UTF-8, чтобы он знал, как правильно отображать символы. Вы делаете это, добавляя ; charset=utf-8 к заголовку Content-Type:, который вы отправляете вместе с текстовым содержимым.

Например, в начало PHP-скрипта, создающего HTML-код в кодировке UTF-8, вы должны добавить следующую строку:

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

Также рекомендуется объявлять набор символов документа в самом документе. Это объявление должно стоять перед любыми не-ascii-символами, существующими в документе, поэтому рекомендуется поместить следующий тег <meta> в качестве первого дочернего тега <head>:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Если вы создаете XHTML с объявлением XML вверху, набор символов может быть объявлен там вместо использования тега <meta>:

<?xml version="1.0" encoding="UTF-8" ?>

Помните, что использование определения набора символов в заголовке Content-Type: не ограничивается text/html — это имеет смысл в контексте любого типа MIME семейства text/*.

Дополнительная литература: Что абсолютно необходимо знать каждому программисту о кодировках и наборах символов для работы с текстом

Также не забудьте проверить разметку.

person DaveRandom    schedule 30.08.2012
comment
Почему по умолчанию для моего mySQL все равно установлено значение latin1_swedish_ci ? ^^ - person 1252748; 05.09.2012
comment
Кроме того, utf8_unicode_ci был самым близким элементом в моем списке к предложенной вами UTF-8. На самом деле UTS-8 было примерно столько же, сколько языков. Хоть и не английский как ни странно. Считаете ли вы этот выбор удовлетворительным. Был также UTF8-бин. Еще раз спасибо за вашу помощь и отличный ответ! - person 1252748; 05.09.2012
comment
@thomas Проблема шведского языка по умолчанию решается здесь - в общем, никто толком не знает. Если вы действительно хотите знать, в чем разница между различными сопоставлениями UTF-8, всю необходимую информацию можно найти здесь. У меня лично есть более важные дела в жизни... ;-). Суть в том, что если все, о чем вы беспокоитесь, это поддержка западного текста и расширенной пунктуации, подойдет любой. - person DaveRandom; 05.09.2012
comment
Если ты не волнуешься, то и я не волнуюсь. :) Спасибо за помощь. Это все исправило. - person 1252748; 05.09.2012