user1632874
user1632874

Reputation: 95

php converting preg_replace to preg_replace_callback

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?

Upvotes: 5

Views: 2480

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626802

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";

Upvotes: 8

Related Questions