Jump to content

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


 Share

Recommended Posts

I'm using a game stats processor for my site called VSP. I've corrected all the /e modifier errors using the preg_replace_callback function except for this one. I'm hoping someone can help. The code is:

$V341be97d = preg_replace('/\^([^\^<])/e', "'`' . \$V70dda5df[ord('\\1') % 8]", $V341be97d);

I'm attaching the entire php file for reference. 

 

Edited by requinix
removing copyrighted file
Link to comment
Share on other sites

No offense but I've removed the file from your post. It doesn't look like something that's meant to be shared, but it also doesn't need to be to address this particular problem.
I don't suppose there's a more up to date version of this script available, right? Because that would be ideal.

If not, what did you try? The second argument is essentially PHP code, so you just need to translate that string into normal code and use it with preg_replace_callback...

Link to comment
Share on other sites

Posted (edited)
25 minutes ago, requinix said:

I don't suppose there's a more up to date version of this script available, right? Because that would be ideal.

If not, what did you try? The second argument is essentially PHP code, so you just need to translate that string into normal code and use it with preg_replace_callback...

It's the latest working version of the script. There's supposedly a newer version, but I downloaded it and the files are corrupt. I'm not a coder, but I was able to replace other instances of the /e modifier using research. I replaced:

//change: special chars
          if ($this->V93da65a9['xp_version'] <= 103) {
              // 1.03 special chars
              $V341be97d = preg_replace("/\+([\x01-\x7F])#/e", "chr(ord('\\1') + 127)", $V341be97d);
          } else {
              // 1.04 special chars
              $V341be97d = preg_replace("/#(#|[0-9a-f]{2})/ie", "'\\1' == '#' ? '#' : chr(hexdec('\\1'))", $V341be97d);
          }

to this:

//change: special chars
          if ($this->V93da65a9['xp_version'] <= 103) {
              // 1.03 special chars
              $V341be97d = preg_replace_callback("/\+([\x01-\x7F])#/",
      function($matches){
        foreach($matches as $match){
            return chr($match);
        }
    }, 
      $V341be97d
);
          } else {
              // 1.04 special chars
              $V341be97d = preg_replace_callback("/#(#|[0-9a-f]{2})/",
    function($matches){
        foreach($matches as $match){
            return chr($match);
        }
    }, 
    $V341be97d
);

Those changes work without errors. I just can't seem to get the code in my first post to work correctly. Here's a link to the program I'm using. 

Edited by bobl61
Link to comment
Share on other sites

It's a shame the code is open-source but extremely unreadable...

 

I'll use those two as an example. Moving away from /e goes basically like:

1. Switch the function to preg_replace_callback and drop the /e flag, obviously.

2. Change the second argument (a string) to be a function following the template

function($matches) {
	return ___;
}

where you put in there the replacement string but minus the outer quotes.

3. Replace "\\1" with $matches[1], "\\2" with $matches[2], and so on, and correct any issues with the PHP syntax.

 

So this

preg_replace("/\+([\x01-\x7F])#/e", "chr(ord('\\1') + 127)", $V341be97d)

starts as

preg_replace_callback("/\+([\x01-\x7F])#/", function($matches) {
	return chr(ord('\\1') + 127);
}, $V341be97d)

and you replace the '\\1' string to get

preg_replace_callback("/\+([\x01-\x7F])#/", function($matches) {
	return chr(ord($matches[1]) + 127);
}, $V341be97d)

What you have now is quite a bit different to the point that it won't actually work correctly.

If you're using PHP 7.4 or later, you can simplify the function syntax if you want by using a function shorthand: function(...) { return ... } can be shortened to fn(...) => ...

preg_replace_callback("/\+([\x01-\x7F])#/", fn($matches) => chr(ord($matches[1]) + 127), $V341be97d)

 

The second one

preg_replace("/#(#|[0-9a-f]{2})/ie", "'\\1' == '#' ? '#' : chr(hexdec('\\1'))", $V341be97d)

is similar

preg_replace_callback("/#(#|[0-9a-f]{2})/i", function($matches) {
	return '\\1' == '#' ? '#' : chr(hexdec('\\1'));
}, $V341be97d)

but has a little more to replace, creating

preg_replace_callback("/#(#|[0-9a-f]{2})/i", function($matches) {
	return $matches[1] == '#' ? '#' : chr(hexdec($matches[1]));
}, $V341be97d)

or with the PHP 7.4 shorthand,

preg_replace_callback("/#(#|[0-9a-f]{2})/i", fn($matches) => $matches[1] == '#' ? '#' : chr(hexdec($matches[1])), $V341be97d)

 

The latest one you're working on

preg_replace('/\^([^\^<])/e', "'`' . \$V70dda5df[ord('\\1') % 8]", $V341be97d)

goes very much the same way

preg_replace_callback('/\^([^\^<])/', function($matches) {
	return '`' . \$V70dda5df[ord('\\1') % 8];
}, $V341be97d)
preg_replace_callback('/\^([^\^<])/', function($matches) {
	return '`' . \$V70dda5df[ord($matches[1]) % 8];
}, $V341be97d)

except it has a wrinkle: it tries to use the $V70dda5df variable. You need to adjust the syntax a bit by removing the backslash (it was needed because the code lived inside a string) but also for the fact that variables aren't accessible inside functions... unless you explicitly tell PHP you want that with a "use" attached to the function.

That results in,

preg_replace_callback('/\^([^\^<])/', function($matches) use ($V70dda5df) {
	return '`' . $V70dda5df[ord($matches[1]) % 8];
}, $V341be97d)

The thing about variables doesn't apply to shorthand functions, so with PHP 7.4 you could simply write

preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d)

 

  • Thanks 1
Link to comment
Share on other sites

I've implemented your fixes and the program runs without errors. Only problem now is all the players have ^ characters in their names.

 

2022-06-15_054101.png

Link to comment
Share on other sites

Here's what the code looks like now...

//$V70dda5df = array("black", "red", "lime", "yellow", "blue", "aqua", "fuchsia", "white", "orange");
          //change: special chars
          if ($this->V93da65a9['xp_version'] <= 103) {
              // 1.03 special chars
              preg_replace_callback("/\+([\x01-\x7F])#/", fn($matches) => chr(ord($matches[1]) + 127), $V341be97d);
          } else {
              // 1.04 special chars
              preg_replace_callback("/#(#|[0-9a-f]{2})/i", fn($matches) => $matches[1] == '#' ? '#' : chr(hexdec($matches[1])), $V341be97d);
          }
          //endchange
          $V70dda5df = array("#555555", "#e90000", "#00dd24", "#f5d800", "#2e61c8", "#16b4a5", "#f408f1", "#efefef", "#ebbc1b");
          $tmp = array("\xde" => "^");
          $V341be97d = strtr($V341be97d, array_diff_assoc($this->V42dfa3a4['char_trans'], $tmp));
          if ($V341be97d[0] != "^")
              $V341be97d = "^7" . $V341be97d;
          $V341be97d = preg_replace('/\^(a[1-9]|[fFrRbBl])/', "", $V341be97d);
          $V341be97d = preg_replace('/\^s(\^x[a-fA-F0-9]{6}|\^[^\^])/', "\\1", $V341be97d);
          $V341be97d = preg_replace('/\^s/', "^7", $V341be97d);
          $V341be97d = preg_replace('/(\^(x[a-fA-F0-9]{6}|[^\^]))\^(x[a-fA-F0-9]{6}|[^\^])/', "\\1", $V341be97d);
          $V341be97d = preg_replace('/\^x([a-fA-F0-9]{6})/i', "`#\\1", $V341be97d);
          preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);
          $V341be97d = strtr($V341be97d, $tmp);
          return $V341be97d;
      }
      function Fa3f5d48d($V341be97d) // parece eliminar efectos del nombre

 

Link to comment
Share on other sites

          $V341be97d = preg_replace('/\^x([a-fA-F0-9]{6})/i', "`#\\1", $V341be97d);
          preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);

On that second line you lost the assignment that was on the left of the function. So preg_replace_callback is running but the result isn't going anywhere.

(what I posted was meant as only the bit about the function, not to be the whole line)

Link to comment
Share on other sites

2 hours ago, requinix said:
          $V341be97d = preg_replace('/\^x([a-fA-F0-9]{6})/i', "`#\\1", $V341be97d);
          preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);

On that second line you lost the assignment that was on the left of the function. So preg_replace_callback is running but the result isn't going anywhere.

(what I posted was meant as only the bit about the function, not to be the whole line)

Uhhh... you lost me. I'm not sure what you mean.

Link to comment
Share on other sites

The original line was

$V341be97d = preg_replace('/\^([^\^<])/e', "'`' . \$V70dda5df[ord('\\1') % 8]", $V341be97d);

That was updating $V341be97d, on the left-hand side of the = assignment, with a new value coming from preg_replace. Your updated version

preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);

changed the preg_replace into a preg_replace_callback but it lost the $V341be97d= that was there before. Still need it, otherwise whatever this replacement was designed to handle (namely the ^0s and ^7s and such that you're now seeing) won't happen.

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, requinix said:

The original line was

$V341be97d = preg_replace('/\^([^\^<])/e', "'`' . \$V70dda5df[ord('\\1') % 8]", $V341be97d);

That was updating $V341be97d, on the left-hand side of the = assignment, with a new value coming from preg_replace. Your updated version

preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);

changed the preg_replace into a preg_replace_callback but it lost the $V341be97d= that was there before. Still need it, otherwise whatever this replacement was designed to handle (namely the ^0s and ^7s and such that you're now seeing) won't happen.

Okay, got it. Definitely getting closer. Players with special characters in their names are still not displaying properly, though.

2022-06-15_194315.png.1b996226533a7374fa94ca7fe68f5c29.png

Here's what I ahve now...

//$V70dda5df = array("black", "red", "lime", "yellow", "blue", "aqua", "fuchsia", "white", "orange");
          //change: special chars
          if ($this->V93da65a9['xp_version'] <= 103) {
              // 1.03 special chars
          $V341be97d = preg_replace_callback("/\+([\x01-\x7F])#/", fn($matches) => chr(ord($matches[1]) + 127), $V341be97d);
          } else {
              // 1.04 special chars
          $V341be97d = preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);
          }
          //endchange
          $V70dda5df = array("#555555", "#e90000", "#00dd24", "#f5d800", "#2e61c8", "#16b4a5", "#f408f1", "#efefef", "#ebbc1b");
          $tmp = array("\xde" => "^");
          $V341be97d = strtr($V341be97d, array_diff_assoc($this->V42dfa3a4['char_trans'], $tmp));
          if ($V341be97d[0] != "^")
              $V341be97d = "^7" . $V341be97d;
          $V341be97d = preg_replace('/\^(a[1-9]|[fFrRbBl])/', "", $V341be97d);
          $V341be97d = preg_replace('/\^s(\^x[a-fA-F0-9]{6}|\^[^\^])/', "\\1", $V341be97d);
          $V341be97d = preg_replace('/\^s/', "^7", $V341be97d);
          $V341be97d = preg_replace('/(\^(x[a-fA-F0-9]{6}|[^\^]))\^(x[a-fA-F0-9]{6}|[^\^])/', "\\1", $V341be97d);
          $V341be97d = preg_replace('/\^x([a-fA-F0-9]{6})/i', "`#\\1", $V341be97d);
          $V341be97d = preg_replace_callback('/\^([^\^<])/', fn($matches) => '`' . $V70dda5df[ord($matches[1]) % 8], $V341be97d);
          $V341be97d = strtr($V341be97d, $tmp);
          return $V341be97d;
          }
          function Fa3f5d48d($V341be97d) // parece eliminar efectos del nombre

BTW - I really appreciate all your help.

Link to comment
Share on other sites

8 hours ago, requinix said:

I don't see what would be responsible. Did you alter any other files?

Only the theme. Changed some images and banners. Nothing to do with the processing of the stats. I did see this further down the file. I forgot that I changed this also...

 

//change: special chars
                  if ($this->V93da65a9['xp_version'] <= 103) {
                      // 1.03 special chars
                      $Vaa8af3eb = preg_replace("/\+([\x01-\x7F])#/e", "chr(ord('\\1') + 127)", $Vaa8af3eb);
                  } else {
                      // 1.04 special chars
                      $Vaa8af3eb = preg_replace("/#(#|[0-9a-f]{2})/ie", "'\\1' == '#' ? '#' : chr(hexdec('\\1'))", $Vaa8af3eb);
                  }
                  $Vaa8af3eb = strtr($Vaa8af3eb, $this->V42dfa3a4['char_trans']);
                  //endchange
                  $this->Vae2aeb93->F8405e6ea($this->Va2bbabfe[$V2bfe9d72]['id'], $this->F7212cda9($Vaa8af3eb));
              }
              return true;
          }
          return false;
      }
      function Fe7c49e90(&$V6438c669) // si descongela (oO, no sabía esto)
      {

To this...

 

//change: special chars
                  if ($this->V93da65a9['xp_version'] <= 103) {
                      // 1.03 special chars
                      $Vaa8af3eb = preg_replace_callback("/\+([\x01-\x7F])#/",
        function($matches){
        foreach($matches as $match){
            return chr($match);
        }
    }, 
    $Vaa8af3eb
);
                  } else {
                      // 1.04 special chars
                     $Vaa8af3eb = preg_replace_callback("/#(#|[0-9a-f]{2})/",
        function($matches){
        foreach($matches as $match){
            return chr($match);
        }
    }, 
    $Vaa8af3eb
);

Maybe that's causing it?

Link to comment
Share on other sites

WOO-HOO! Everything is working perfectly now. The player names are perfect. The country flags are working properly. 

Thanks so much for your help requinix!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.