Ответ 1
Это звучит как проблема с Unicode. У Джоэла Спольски есть хороший прыжок с темы: http://www.joelonsoftware.com/articles/Unicode.html
У меня есть форма с текстовым полем. Пользователи вводят блок текста, который хранится в базе данных.
Иногда пользователь вставляет текст из Word, содержащего интеллектуальные кавычки или emdash. Эти символы появляются в базе данных как: ",", "¬", "
Какую функцию я должен вызывать на входной строке для преобразования умных кавычек в обычные кавычки и emdash в обычные тире?
Я работаю в PHP.
Обновление: Спасибо за все замечательные ответы. Страница на сайте Joel о кодировках очень информативна: http://www.joelonsoftware.com/articles/Unicode.html
Некоторые заметки о моей среде:
В базе данных MySQL используется кодировка UTF-8. Аналогично, страницы HTML, отображающие контент, используют UTF-8 (Update:), явно устанавливая тип метаконтента.
На этих страницах умные кавычки и emdash появляются как алмаз с вопросительным знаком.
Решение:
Еще раз спасибо за ответы. Решение было двояким:
htmlspecialchars()
вместо
htmlentities()
.Это звучит как проблема с Unicode. У Джоэла Спольски есть хороший прыжок с темы: http://www.joelonsoftware.com/articles/Unicode.html
В базе данных mysql используется UTF-8 кодирование. Аналогично, html-страницы которые отображают содержимое, используют UTF-8.
Содержимое HTML может быть в UTF-8, да, но явно ли вы устанавливаете тип содержимого (кодирование) ваших HTML-страниц (сгенерированных через PHP?) в UTF-8? Попробуйте вернуть заголовок Content-Type
"text/html;charset=utf-8"
или добавить теги <meta>
в свои HTML файлы:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
Таким образом, тип содержимого данных, передаваемых в PHP, также будет таким же.
У меня была аналогичная проблема, и добавление тега <meta>
работало для меня.
Похоже, что реальная проблема заключается в том, что ваша база данных не использует ту же кодировку символов, что и ваша страница (что, вероятно, должно быть UTF-8). В этом случае, если какой-либо пользователь отправляет символ не ASCII, вы, вероятно, увидите странные символы в базе данных. Поиск и исправление только некоторых из них (фигурные кавычки и em-тире) не решает реальной проблемы.
Ниже приведена информация о переносе вашей базы данных на другую кодировку символов, по крайней мере для базы данных MySQL.
Это, к сожалению, слишком распространенная проблема, а не очень плохое управление PHP наборами символов.
Что мы делаем, это заставить текст через iconv
// Convert input data to UTF8, ignore any odd (MS Word..) chars
// that don't translate
$input = iconv("ISO-8859-1","UTF-8//IGNORE",$input);
Флаг //IGNORE
означает, что все, что не может быть переведено, будет выброшено.
Если вы добавляете строку //IGNORE, символы, которые не могут быть представлены в целевой кодировке, молча отбрасываются.
Мы часто использовали стандартные функции замены строк для этого. Несмотря на то, что характер ASCII/Unicode в этом контексте довольно мрачен, он работает. Просто убедитесь, что ваш php файл сохранен в правильном формате кодирования и т.д.
По моему опыту, проще просто принять умные кавычки и убедиться, что вы используете ту же самую кодировку везде. Для начала добавьте это в свой тег формы: accept-charset="utf-8"
Вы можете попробовать mb_ convert_encoding от ISO-8859-1 до UTF-8.
$str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1');
Это предполагает, что вы хотите UTF-8, и конвертер может найти разумные замены... если нет, mb_str_replace или preg_replace их самостоятельно.
Вы должны быть уверены, что ваше соединение с базой данных настроено на прием и предоставление UTF-8 от клиента и к нему (в противном случае он преобразуется в значение "по умолчанию", которое обычно является latin1).
На практике это означает выполнение запроса SET NAMES 'utf8';
http://www.phpwact.org/php/i18n/utf-8/mysql
Кроме того, умные кавычки являются частью набора символов windows-1252, а не iso-8859-1 (латинский-1). Не очень важно для вашей проблемы, но просто FYI. Здесь также присутствует символ евро.
проблема в кодировке mysql, я исправил свои проблемы с помощью этой строки кода.
mysql_set_charset('utf8',$link);
Вам необходимо вручную изменить сортировку отдельных столбцов на UTF8; изменение общей базы данных не изменит их.
Если вы искали, чтобы избежать этих символов для Интернета, а сохраняя их внешний вид, ваши строки будут выглядеть следующим образом: "Его приятно!" , а не "Это скучно" ...
Вы можете сделать это, используя собственную пользовательскую функцию htmlEncode вместо PHP htmlentities():
$trans_tbl = false;
function htmlEncode($text) {
global $trans_tbl;
// create translation table once
if(!$trans_tbl) {
// start with the default set of conversions and add more.
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl[chr(130)] = '‚'; // Single Low-9 Quotation Mark
$trans_tbl[chr(131)] = 'ƒ'; // Latin Small Letter F With Hook
$trans_tbl[chr(132)] = '„'; // Double Low-9 Quotation Mark
$trans_tbl[chr(133)] = '…'; // Horizontal Ellipsis
$trans_tbl[chr(134)] = '†'; // Dagger
$trans_tbl[chr(135)] = '‡'; // Double Dagger
$trans_tbl[chr(136)] = 'ˆ'; // Modifier Letter Circumflex Accent
$trans_tbl[chr(137)] = '‰'; // Per Mille Sign
$trans_tbl[chr(138)] = 'Š'; // Latin Capital Letter S With Caron
$trans_tbl[chr(139)] = '‹'; // Single Left-Pointing Angle Quotation Mark
$trans_tbl[chr(140)] = 'Œ'; // Latin Capital Ligature OE
// smart single/ double quotes (from MS)
$trans_tbl[chr(145)] = '‘';
$trans_tbl[chr(146)] = '’';
$trans_tbl[chr(147)] = '“';
$trans_tbl[chr(148)] = '”';
$trans_tbl[chr(149)] = '•'; // Bullet
$trans_tbl[chr(150)] = '–'; // En Dash
$trans_tbl[chr(151)] = '—'; // Em Dash
$trans_tbl[chr(152)] = '˜'; // Small Tilde
$trans_tbl[chr(153)] = '™'; // Trade Mark Sign
$trans_tbl[chr(154)] = 'š'; // Latin Small Letter S With Caron
$trans_tbl[chr(155)] = '›'; // Single Right-Pointing Angle Quotation Mark
$trans_tbl[chr(156)] = 'œ'; // Latin Small Ligature OE
$trans_tbl[chr(159)] = 'Ÿ'; // Latin Capital Letter Y With Diaeresis
ksort($trans_tbl);
}
// escape HTML
return strtr($text, $trans_tbl);
}
Это может быть не лучшее решение, но я бы попробовал тестирование, чтобы узнать, что видит PHP. Скажем, он видит "â €" (есть еще несколько возможностей, таких как простой "или" & # 8220;"). Затем сделайте str_replace, чтобы избавиться от всех этих и заменить их обычными кавычками, прежде чем набивать ответ в базе данных.
Лучшее решение, вероятно, будет связано с тем, что сквозные данные передают все UTF-8, поскольку люди пытаются помочь в других ответах.
На самом деле проблема не возникает в PHP, но это происходит в JavaScript, она из-за копирования/вставки из Word, поэтому вам нужно решить вашу проблему в JavaScript, прежде чем передавать текст на PHP, см. этот ответ fooobar.com/info/203714/....