この問題にご協力いただきありがとうございます。
preg_match():コンパイルに失敗しました:278行目のオフセット20 session.phpの文字クラスの無効な範囲
サーバーでのPHPアップグレード後、数か月の作業の後、これは突然動作しなくなりました。
ここにコードがあります
else{
/* Spruce up username, check length */
$subuser = stripslashes($subuser);
if(strlen($subuser) < $config['min_user_chars']){
$form->setError($field, "* Username below ".$config['min_user_chars']."characters");
}
else if(strlen($subuser) > $config['max_user_chars']){
$form->setError($field, "* Username above ".$config['max_user_chars']."characters");
}
/* Check if username is not alphanumeric */
/* PREG_MATCH CODE */
else if(!preg_match("/^[a-z0-9]([0-9a-z_-\s])+$/i", $subuser)){
$form->setError($field, "* Username not alphanumeric");
}
/* PREG_MATCH CODE */
/* Check if username is reserved */
else if(strcasecmp($subuser, GUEST_NAME) == 0){
$form->setError($field, "* Username reserved Word");
}
/* Check if username is already in use */
else if($database->usernameTaken($subuser)){
$form->setError($field, "* Username already in use");
}
/* Check if username is banned */
else if($database->usernameBanned($subuser)){
$form->setError($field, "* Username banned");
}
}
文字クラスの範囲は、文字クラスの2つの値の間に-を使用して定義されます(正規表現では[]
)。 [0-9]
は、0から9までのすべてを意味します。コードの正規表現には、いくつかの文字クラス範囲、a-z
、0-9
があります。また、おそらくそこに置くつもりはなかったクラスが1つあります。それは_-\s
です。
"/^[a-z0-9]([0-9a-z_-\s])+$/i"
^^^^
これは、PCREのいくつかの(ほとんどの?)バージョン(正規表現ライブラリPHP使用))で無効な文字範囲とは見なされませんが、最近変更された可能性があり、PCREライブラリがアップグレードされた場合サーバー上で、それが理由である可能性があります。
Debuggex は、エラーのデバッグに役立つ素敵なツールです(PHPからのエラーメッセージは、行andエラーがあった場所の文字、つまり..)このように(私は提携していない、ただのファンです)。
エラーは正規表現インタープリターに依存しています。
その使用法を明確にするためにハイフンをエスケープできます。 \-
の代わりに-
を使用する意味。
最終コード:
/^[a-z0-9]([0-9a-z_\-\s])+$/i
問題は本当に古いですが、PHP 7.3以降のバージョンをカバーする必要があることに関連するいくつかの新しい開発があります。PHP PCREエンジンはPCRE2に移行します PHP 7.3は10.32で使用され、それは 後方互換性のない変更 の起源です:
- 内部ライブラリAPIが変更されました
- 「S」修飾子は効果がなく、パターンは自動的に調査されます。実質的な影響はありません。
- 「X」修飾子は、PCRE2のデフォルトの動作です。現在のパッチは、PCREでの動作を「X」の意味に戻しますが、新しい動作を使用し、デフォルトで「X」をオンにする方がよい場合があります。そのため、現時点では影響もありません。
- より新しいUnicodeエンジンによるいくつかの動作の変更が確認されました。 PCRE2のUnicode 10とPCREのUnicode 7です。無効なパターンを使用すると、一部の動作の変更を確認できます。
Acc。 PHP 10.33 changelog:
PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
を設定すると、\s
などのエスケープシーケンスは文字クラスで有効ですが、範囲の終わりとしてではなく、リテラルとして扱われていました。例は[_-\s]
です(ただし、範囲のstartでエラーが発生したため、[\s-_]
ではありません)。 「無効な範囲」エラーがPCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
。とは別に与えられます
PHP 7.3より前では、文字クラスでハイフンを使用する場合、エスケープする場合、または "を示すと解釈できない位置に配置する場合があります。範囲」 。PHP 7.3では、PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
がfalseに設定されたようです。したがって、今後は、ハイフンを文字クラスに入れるために、- 常に開始位置または終了位置でのみ使用する。
このリファレンス も参照してください:
簡単に言えば、
PCRE2はパターンの検証がより厳密であるため、アップグレード後、既存のパターンの一部はコンパイルできなくなりました。
これは、php.netで使用される簡単なスニペットです。preg_match( '/ [\ w-。] + /'、 ''); //これはPHP7.3では機能しません preg_match( '/ [\ w \-。] + /'、 ''); //ハイフンをエスケープする必要があります上記の例からわかるように、2つの行にはわずかではありますが実質的な違いがあります。