2016-08-24 2 views
6

関数mb_detect_encodingにはstrictモード用のパラメータがあります。まず、最もupvotedコメントでPHP関数mb_detect_encoding strictモード

<?php 
$str = 'áéóú'; // ISO-8859-1 
mb_detect_encoding($str, 'UTF-8'); // 'UTF-8' 
mb_detect_encoding($str, 'UTF-8', true); // false 

これははい、本当です。しかし、誰も私に説明を与えることができます、なぜそれは?

+1

で、このためのレポートを開いた*


c72282a13b12b7e572469eba7a7ce593d900a8a2/ext/mbstring/libmbfl/mbfl/mbfilter.c#L718);しかし、私はそれが何かを把握することができれば私は気になるでしょう... – deceze

+0

FWIW、*もう一つの理由は、*検出*エンコーディングは基本的に不可能なので、この機能を使用しないでください。それにもかかわらず、非常に興味深い質問です。 – deceze

+0

@deceze面白い:ソースコード全体の 'strict'に関する唯一のコメントは'/* set strict flag */'です。 –

答えて

4

この回答のすべては私のコードherehereの私の読書に基づいています。

私はそれを書いていない、私はデバッガでそれを踏んでいない、これは私の解釈のみです。


非strictモードがはの一部であり得ることをサブシーケンスを可能にしながら、意思は、全体として文字列をエンコードするために有効であったかどうかを確認するために厳格なモードのためだったようです有効な文字列。たとえば、文字列がマルチバイト文字の最初のバイトになるように終了した場合、strictモードでは一致しませんが、非strictモードではUTF-8として修飾されます。

ただし、厳密でないモードでは、状況によっては文字列の最初のバイトだけがチェックされているバグがあるようです。

例:

バイト0xf8はUTF-8にはどこにも許可されていません。文字列の先頭に配置すると、mb_detect_encoding()は、どのモードが使用されているかにかかわらず、正しくfalseを返します。

$str = "\xf8foo"; 

var_dump(
    mb_detect_encoding($str, 'UTF-8'),  // bool(false) 
    mb_detect_encoding($str, 'UTF-8', true) // bool(false) 
); 

しかし限り先頭バイトはUTF-8配列のどこにでも起こり得るように、非厳密モードはUTF-8を返します。

$str = "foo\xf8"; 

var_dump(
    mb_detect_encoding($str, 'UTF-8'),  // string(5) "UTF-8" 
    mb_detect_encoding($str, 'UTF-8', true) // bool(false) 
); 

だから、あなたのISO-8859-1文字列 'áéóú'は、有効なUTF-8、UTF-8と mb_detect_encoding()誤っような文字列を返すに発生する可能性があります最初のバイト "\xe1"ない間。私は最終的にそのフラグは[こちら](https://github.com/php/php-src/blob/に通過します https://bugs.php.net/bug.php?id=72933

-2

$strは実際にはUTF-8ではありませんが、ISO-8859-1です。ないときは厳密な比較ので、UTF-8ISO-8859-1と同じ処理することができるが、厳密なモードを使用する場合のみUTF-8UTF-8比較(explained here)としてISO-8859-1エンコードで

+1

これらの特定の文字は、UTF-8と8859では非常に異なって見えます。それらは同じではなく、同じ扱いができません。これは最初の128文字(ASCII)にのみ当てはまりますが、これは該当しません。その文字列は、UTF-8で無期限です。 – deceze

2

áéóúの実際のフィット:

e1 e9 f3 fa 

UTF-8として誤って解釈すると、無効なバイトシーケンスが4つしか取得されません。マルチバイト拡張は、基本的にエラーを無視するように設計されています。たとえば、mb_convert_encoding()は、question marksまたはmb_substitute_character()で設定したものと置き換えられます。

  • false
  • trueあなたはこれらを無視した場合、それらを

を維持することを意味し、それらを削除することを意味する:

私の推測では、厳密なエンコーディングが無効なバイトシーケンスを使って何をすべきかを決定するということです無効なシーケンスは、明らかに非常に貴重な情報を破棄しており、非常に限られた状況では賢明な結果しか得られません。

$str = chr(81); 
var_dump(mb_detect_encoding($str, ['ISO-8859-1', 'Windows-1252'])); 
var_dump(mb_detect_encoding($str, ['Windows-1252', 'ISO-8859-1'])); 

まとめると、mb_detect_encoding()は一般的に、あなたが事かもしれないほど有用ではありません、それはデフォルトのパラメータで合計がらくたです。

+0

笑い声か叫ぶかは問われます。 – deceze

関連する問題