У меня есть форма с текстовым полем. Пользователи вводят блок текста, который хранится в базе данных.
Иногда пользователь вставляет текст из Word, содержащий интеллектуальные кавычки или символы emdash. Эти символы появляются в базе данных: â € »,« â € »,« â € œ,
Какую функцию я должен вызывать на входной строке для преобразования умных кавычек в обычные кавычки и emdashes в обычные тире ?
Я работаю в PHP.
Обновление: Спасибо за все замечательные ответы. Страница сайта Joel о кодировках очень информативна: http://www.joelonsoftware.com/articles/Unicode.html
Некоторые заметки о моей среде:
База данных MySQL использует кодировку UTF-8. Аналогично, страницы HTML, отображающие контент, используют UTF-8 (Update :), явно устанавливая мета-контент-тип.
На этих страницах смарт-цитаты и эмпаши появляются как бриллиант с вопросительным знаком.
Решение:
Еще раз спасибо за ответы. Решение было двояким:
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, вы, вероятно, увидите странные символы в базе данных. Поиск и исправление только некоторых из них (фигурные кавычки и эмпирические символы) не решает реальной проблемы.
Вот некоторая информация о переносе вашей базы данных на другую кодировку символов , по крайней мере, для базы данных 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 от клиента и к нему (в противном случае он преобразуется в «default», который обычно является 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 вместо htmlentities () PHP:
$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, см. Этот ответ https: // stackoverflow.com/a/6219023/1857295 .