php converting preg_replace to preg_replace_callback
Asked Answered
A

1

5

I'm working on this old code, and ran across this - which fails:

preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $sObject);

It tells me that preg_replace e modifier is deprecated, and to use preg_replace_callback instead.

From what I understand, I am supposed to replace the 's:'.strlen('$2').':\"$2\";' part with a callback function that does the replacement on the match.

What I DON'T quite get, is exactly what the regexp is doing that I'll be replacing. It's part of a bit to take php serialized data stuffed in a database field (dumb, I know ...) with broken length fields and fix them for reinsertion.

So can anybody explain what that bit is doing, or what I should replace it with?

Atrophy answered 8/2, 2016 at 21:24 Comment(0)
P
8

Use

preg_replace_callback('!s:(\d+):"(.*?)";!', function($m) {
      return 's:' . strlen($m[2]) . ':"' . $m[2] . '";';
}, $sObject);

The !e modifier must be removed. $2 backreferences must be replaced with $m[2] where $m is a match object containing match value and submatches and that is passed to the anonymous function inside preg_replace_callback.

Here is a demo where the digits after s: get replaced with the $m[2] length:

$sObject = 's:100:"word";';
$res = preg_replace_callback('!s:(\d+):"(.*?)";!', function($m) {
      return 's:' . strlen($m[2]) . ':"' . $m[2] . '";';
}, $sObject);
echo $res; // => s:4:"word";
Proudman answered 8/2, 2016 at 21:29 Comment(5)
Nice - a note to use the return value of preg_replace_callback() as the outputManual
I guess OP knows about string immutability. I will add a demo.Maxantia
Yes, I'm using the return value as the output. So far, it looks like it's doing it's job, and this is the correct answer. There are other parts of the code that aren't working properly, namely that the serialized strings I'm jacking with appear to be multidimensional arrays. Whoever decided it was a good idea to stuff serialized php data into a database should be hung, stabbed, shot THEN killed!Atrophy
How would i convert $content = preg_replace('/\{([A-Z_]+)\}/e', "$1", $content); to preg_replace_callback function?Hora
@JonnyDevv No need of callbacks, remove e.Maxantia

© 2022 - 2024 — McMap. All rights reserved.