Textareaのあるフォームがあります。ユーザーは、データベースに保存されているテキストのブロックを入力します。
時折、ユーザーはスマートクォートまたはエムダッシュを含むWordからのテキストを貼り付けるでしょう。これらの文字は、データベースに「」、「」、「」、「」として表示されます。
入力文字列に対してどの関数を呼び出す必要がありますかスマートクォートを通常のクォートに変換し、emdashを通常のダッシュに変換します?
私はPHPで働いています。
更新:これまでのすべての素晴らしい回答に感謝します。エンコーディングに関するJoelのサイトのページは非常に有益です: http://www.joelonsoftware.com/articles/Unicode.html
私の環境に関するいくつかのメモ:
MySQLデータベースはUTF-8エンコーディングを使用しています。同様に、コンテンツを表示するHTMLページは、メタコンテンツタイプを明示的に設定することにより、UTF-8(更新:)を使用しています。
これらのページでは、スマートな引用符とemdashが疑問符の付いたひし形として表示されます。
解決:
回答ありがとうございます。解決策は2つありました。
htmlspecialchars()
の代わりにhtmlentities()
を使用してください。これはUnicodeの問題のように聞こえます。 Joel Spolskyは、このトピックに関する優れた出発点を持っています: 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"
ヘッダーを返すか、HTMLに<meta>
タグを追加してみてください。
<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を追加すると、ターゲット文字セットで表現できない文字は黙って破棄されます。
データベース接続がクライアントとの間でUTF-8を受け入れて提供するように構成されていることを確認する必要があります(そうでない場合は、「デフォルト」(通常はlatin1)に変換されます)。
実際には、これはクエリSET NAMES'utf8 'を実行することを意味します。
http://www.phpwact.org/php/i18n/utf-8/mysql
また、スマートクォートはwindows-1252文字セットの一部であり、iso-8859-1(latin-1)ではありません。あなたの問題とはあまり関係がありませんが、参考までに。ユーロ記号もそこにあります。
問題はmysql文字セットにあります。このコード行の問題を修正しました。
mysql_set_charset('utf8',$link);
そのために、標準の文字列置換関数を使用することがよくあります。そのコンテキストでの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が必要であり、convertが妥当な置換を見つけることができることを前提としています...そうでない場合は、mb_str_replaceまたはpreg_replaceを自分で実行します。
Ifこれらの文字をWebでエスケープしようとしていたときに、preservingの外観なので、文字列は次のように表示されます。"It's Nice!""それは退屈です" ..ではなく.
これを行うには、PHPの代わりに独自のカスタムhtmlEncode関数を使用します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);
}
個々の列の照合順序を手動でUTF8に変更する必要があります。データベース全体を変更しても、これらは変更されません。
実際には問題はPHPでは発生していませんが、JavaScriptで発生しています。これは、Wordからのコピー/貼り付けが原因であるため、テキストをPHPに渡す前にJavaScriptで問題を解決する必要があります。 、この回答を参照してください https://stackoverflow.com/a/6219023/1857295 。