preg_match(): ошибка компиляции: недопустимый диапазон в классе символов со смещением
Заранее благодарю за то, что уделили время на помощь в этом вопросе
preg_match(): ошибка компиляции: недопустимый диапазон в классе символов по смещению 20 session.php в строке 278
Это перестало работать внезапно после нескольких месяцев работы, после обновления 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");
}
}
Ответы
Ответ 1
Диапазон классов символов определяется с помощью - между двумя значениями в символьном классе ([]
в регулярном выражении). [0-9]
означает все между 0 и 9 включительно. В регулярном выражении в вашем коде у вас есть несколько диапазонов классов символов, a-z
, 0-9
. Существует также один класс, который вы, вероятно, не хотели его указывать, а именно _-\s
.
"/^[a-z0-9]([0-9a-z_-\s])+$/i"
^^^^
Это, по-видимому, не считается недопустимым диапазоном символов в некоторых (большинство?) версиях PCRE (используется библиотека регулярных выражений PHP), но в последнее время она может быть изменена, и если библиотека PCRE была обновлена на сервере, это может быть причиной.
Debuggex - хороший инструмент, который может помочь отлаживать ошибки (ну, сообщение об ошибке с PHP рассказало вам как строку, так и символ где ошибка была, так что..) вот так (я не аффилирован, просто фанат).
Ответ 2
Ваша ошибка зависит от вашего переводчика регулярных выражений.
Вы можете избежать дефиса, чтобы понять, как его использовать. То есть, используя \-
вместо -
.
Ваш окончательный код:
/^[a-z0-9]([0-9a-z_\-\s])+$/i
Ответ 3
Проблема действительно старая, но есть некоторые новые разработки, связанные с PHP 7.3 и более новыми версиями, которые необходимо охватить. Механизм PHP PCRE мигрирует на PCRE2, и версия PCRElibrary, используемая в PHP 7.3, - 10.32, и именно отсюда происходят несовместимые назад изменения :
-
API внутренней библиотеки изменилось
- Модификатор 'S' не имеет никакого эффекта, шаблоны изучаются автоматически. Никакого реального воздействия.
- Модификатор "X" является поведением по умолчанию в PCRE2. Текущий патч возвращает поведение к значению "X", как это было в PCRE, но, возможно, было бы лучше перейти с новым поведением и включить "X" по умолчанию. Так что в настоящее время никакого влияния тоже нет.
- Было замечено некоторое изменение поведения из-за более нового движка Unicode. Это Unicode 10 в PCRE2 против Unicode 7 в PCRE. Некоторое изменение поведения может быть замечено с недопустимыми образцами.
Точность. в журнал изменений PHP 10.33:
-
С установленным
PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
escape-последовательностями, такими как \s
которые действительны в классах символов, но не в качестве конца диапазонов, были трактуется как литералы. Примером является [_-\s]
(но не [\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-.]+/', ''); // this will not work in PHP7.3
preg_match('/[\w\-.]+/', ''); // the hyphen need to be escaped
Как видно из приведенного выше примера, между этими двумя строками есть небольшая, но существенная разница.
Ответ 4
У меня есть эта ошибка, и я решаю ее, делая это
Route::get('{path}','[email protected]')->where( 'path', '([A-z]+)?' );
и это работа для меня.
Ответ 5
Во-первых,
Route :: get ('{path}', "HomeController @index") → где ('path', '([A-z\d-/_.] +)?');
это не работает для меня тогда, когда я пытаюсь снизу, и это происходит :-)
Route :: get ('{path}', 'HomeController @index') → где ('path', '([A-z] +)?')