3

I recently migrated from php5.2.6 to php5.6.22 and now I am getting this error.

Unkwown error. 8192: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead

Seems that preg_replace is deprecated in php5.6++

http://php.net/manual/en/migration55.deprecated.php

Here is whole function where I am using `preg_replace function:

function mb_unserialize( $serial_str ) {
    $out = preg_replace( '!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
    return unserialize( $out );
}

Could someone explain how should I implement preg_replace_callback function with this type of pattern? And how does preg_replace_callback works in this situation?

Thanks

Mario
  • 3,339
  • 2
  • 22
  • 41
  • `preg_replace` isn't deprecated **but** the non-PCRE `e` (ereg) flag **is**, along with `ereg_replace` - any Perl compatible RegEx is fine. – CD001 Jul 18 '16 at 08:53
  • Thanks for your answer, so basically I just need to improve `preg_replace` patter from `'!s:(\d+):"(.*?)";!se'` to `'/!s:(\d+):"(.*?)";!se/'` and dont need to use `preg_replace_callback` ? – Adomas Kondrotas Jul 18 '16 at 09:11
  • In your original pattern, the `!` are the start and end of the RegEx matching - the final `se` characters are the pattern modifiers (http://php.net/manual/en/reference.pcre.pattern.modifiers.php) - it's the `e` modifier that's defunct. Your pattern should probably be `/s:(\d+):"(.*?)";/s` (though I'd be surprised if you needed the `s` modifier either). – CD001 Jul 18 '16 at 09:21
  • Your suggested patter `/s:(\d+):"(.*?)";/s` don't work as expected, had to leave `!` for correct output. So finally patter is `'/!s:(\d+):"(.*?)";!/s'`, and again thanks for comments. – Adomas Kondrotas Jul 18 '16 at 09:42
  • Ah right, didn't realise the `!` were part of the pattern ;) Thought they were the delimiters (they were acting as such). – CD001 Jul 18 '16 at 15:54

1 Answers1

0

A formal answer:

function mb_unserialize( string $serial_str ):string {
    return unserialize( preg_replace_callback(
        '/s:(?:\d+):"(.*?)";/s', // -- the first pair of parentheses is not used.
        function( array $matches ): string { // -- this is the callback.
            return 's:' . strlen( $matches[1] ) . ':"' . $matches[1] . '";';
        },
        $serial_str
    ));
}
Alexander Mashin
  • 3,892
  • 1
  • 9
  • 15