Кто-нибудь знает, почему это не работает? Работа над: preg_replace(): модификатор /e больше не поддерживается, вместо этого используйте preg_replace_callback

Когда мы перешли на php7, внезапно один из плагинов Wordpress начал выдавать эту ошибку:

preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead.

Итак, я начал искать (я не эксперт по php) и пришел с этим переписыванием вызова.

Что-то определенно не так (хотя ошибка исчезла), потому что плагин не выполняет свою работу. Кто-нибудь подскажет? Спасибо

//old
//$rewrite_rules = unserialize( preg_replace         ( '!s:(\d+):"(.*?)";!se',                        "'s:'.strlen('$2').':\"$2\";'"         , $rewrite_rules ) );
//new
  $rewrite_rules = unserialize( preg_replace_callback( '!s:(\d+):"(.*?)";!s',  function($m) { return ("'s:'.strlen('$m[2]').':\"$m[2]\";'");}, $rewrite_rules ) );

person vlad    schedule 18.01.2017    source источник
comment
У вас все еще есть код, написанный внутри строкового литерала, см. ("'s:'.strlen('$m[2]').':\"$m[2]\";'");   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
Попробуйте preg_replace_callback('!s:(\d+):"(.*?)";!s', function($m) { return "'s:'" . strlen($m[2]) . ':"' . $m[2] . '";\'');}, $rewrite_rules )   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
спасибо за быстрый ввод.   -  person vlad    schedule 18.01.2017
comment
я пробовал с небольшим изменением из-за синтаксической ошибки -> удалил лишнее), но все равно не работает preg_replace_callback('!s:(\d+):"(.*?)";!s', function($m) { return "'s:'" . strlen($m[2]) . ':"' . $m[2] . '";\'';}, $rewrite_rules )   -  person vlad    schedule 18.01.2017
comment
ошибок не выдает, но плагин не работает   -  person vlad    schedule 18.01.2017
comment
Это внутри класса? Каков ввод?   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
это внутри функции, которая находится внутри класса. function filter_rewrite_rules( $rewrite_rules ) {/* some code*/ $rewrite_rules = unserialize( preg_replace_callback('!s:(\d+):"(.*?)";!s', function($m) { return "'s:'" . strlen($m[2]) . ':"' . $m[2] . '";\'';}, $rewrite_rules ) ); }   -  person vlad    schedule 18.01.2017
comment
Смотрите обновленный ответ.   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
спасибо, теперь он выдает это preg_replace_callback(): Requires argument 2, 'UtilString::rewrite_callback', to be a valid callback , которое определенно бьет меня   -  person vlad    schedule 18.01.2017
comment
Может быть, вам следует удалить способ объявления массива и просто передать 'rewrite_callback' в качестве аргумента обратного вызова? Пожалуйста, попробуйте тот, что ниже. Было бы намного проще, если бы вы могли предоставить минимальный полный проверяемый пример (MCVE).   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
См. также stackoverflow.com/questions/6575008/   -  person Wiktor Stribiżew    schedule 18.01.2017
comment
спасибо, я понял вашу мысль (извините за это)   -  person vlad    schedule 18.01.2017


Ответы (1)


Есть несколько проблем с вашим обратным вызовом:

function($m) { return ("'s:'.strlen('$m[2]').':\"$m[2]\";'");}

Самый большой из них заключается в том, что он возвращает строку:

"'s:'.strlen('$m[2]').':\"$m[2]\";'"

Будучи строкой, заключенной в двойные кавычки, переменные заменяются их значениями, но это все. Очевидно, вам нужно также найти длину $m[2] и функцию strlen(). правильный инструмент для этой работы. Но здесь strlen — это всего лишь несколько символов в строке, а не вызов функции. Чтобы правильно вызвать strlen(), чтобы получить длину $m[2], он должен вызываться как PHP-код вне строки, например:

's:'.strlen($m[2]).':"'.$m[2].'";'

Более того, используйте sprintf(), чтобы получить чистый вывод, не беспокоясь о кавычках и экранировании кавычек внутри кавычек и так далее:

function (array $m) {
    return sprintf('s:%d:"%s";', strlen($m[2]), $m[2]);
}
person axiac    schedule 18.01.2017
comment
хорошо объяснил! спасибо @axiac, это сделало работу! извините, я не могу проголосовать из-за репутации профиля! - person vlad; 18.01.2017