本当に良い答えがいくつかあり、ここにあなたの質問に答えようとする試みがあります。私はエンコーディングマスターではありませんが、データベースに至るまで純粋な UTF-8スタックを使用したいという要望を理解しています。utf8mb4
テーブル、フィールド、接続にMySQLのエンコーディングを使用しています。
私の状況は、「データがHTMLフォームまたは電子メール登録リンクからのものである場合に、サニタイザー、バリデーター、ビジネスロジック、および準備済みステートメントがUTF-8を処理するようにしたいだけ」に要約されます。だから、私の簡単な方法で、私はこの考えから始めました:
- エンコーディングを検出しようとしました:
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
- エンコーディングが検出できない場合、
throw new RuntimeException
- 入力がの場合
UTF-8
、続行します。
それ以外の場合、ISO-8859-1
またはASCII
a。UTF-8への変換を試みます(待機し、終了しません)
b。変換された値のエンコーディングを検出する
c。報告されたエンコードと変換された値の両方がUTF-8
である場合は、続行します。
d。そうしないと、throw new RuntimeException
私の抽象クラスから Sanitizer
private function isUTF8($encoding, $value)
{
return (($encoding === 'UTF-8') && (utf8_encode(utf8_decode($value)) === $value));
}
private function utf8tify(&$value)
{
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
mb_internal_encoding('UTF-8');
mb_substitute_character(0xfffd); //REPLACEMENT CHARACTER
mb_detect_order($encodings);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if (!$stringEncoding) {
$value = null;
throw new \RuntimeException("Unable to identify character encoding in sanitizer.");
}
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = mb_convert_encoding($value, 'UTF-8', $stringEncoding);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = null;
throw new \RuntimeException("Unable to convert character encoding from ISO-8859-1, or ASCII, to UTF-8 in Sanitizer.");
}
}
return;
}
エンコーディングの懸念を抽象Sanitizer
クラスから分離し、Encoder
オブジェクトをの具象の子インスタンスに単純に挿入する必要があるという主張をすることができますSanitizer
。ただし、私のアプローチの主な問題は、知識がなければ、不要なエンコードタイプを単純に拒否することです(PHPのmb_ *関数に依存しています)。さらなる研究がなければ、それが一部の集団に害を与えるかどうか、または重要な情報を失うかどうかはわかりません。だから、もっと学ぶ必要があります。この記事を見つけました。
すべてのプログラマーがテキストを処理するためにエンコーディングと文字セットについて確実に知っておくべきこと
さらに、暗号化されたデータが(OpenSSL
またはを使用して)メール登録リンクに追加されるとmcrypt
どうなりますか?これはデコードに干渉する可能性がありますか?Windows-1252はどうですか?セキュリティへの影響はどうですか?使用utf8_decode()
とutf8_encode()
ではSanitizer::isUTF8
疑わしいです。
PHPのmb_ *関数の欠点が指摘されています。調査に時間をかけたことはありませんがiconv
、mb_ * functionsよりもうまく機能する場合はお知らせください。