1

I've just upgraded to PHP 7 and have been hammering out errors associated with deprecated functions, with much success.

Sadly, I've been having trouble fixing the new preg replace methodology for my "view php array in a interactive collapsable javascript thing" code.

The following code:

function print_r_tree($data)
{

// capture the output of $this->print_r_tree
   $out = print_r($data, true);

 // replace something like '[element] => <newline> (' with <a href="javascript:toggleDisplay('...');">...</a><div id="..." style="display: none;">
    $out = preg_replace('/([ \t]*)(\[[^\]]+\][ \t]*\=\>[ \t]*[a-z0-9 \t_]+)\n[ \t]*\(/iUe',"'\\1<a href=\"javascript:toggleDisplay(\''.(\$id = substr(md5(rand().'\\0'), 0, 7)).'\');\">\\2</a><div id=\"'.\$id.'\" style=\"display: none;\">'", $out);

  // replace ')' on its own on a new line (surrounded by whitespace is ok) with '</div>
     $out = preg_replace('/^\s*\)\s*$/m', '</div>', $out);

  // print the javascript function toggleDisplay() and then the transformed output
     echo '<script language="Javascript">function toggleDisplay(id) { document.getElementById(id).style.display = (document.getElementById(id).style.display == "block") ? "none" : "block"; }</script>'."\n$out";

  }

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

Removing the "e" in the first "preg_replace", breaks the javascript thing. I've tried a few preg_replace_callback things as well.

I've been trying to use this link Replace preg_replace() e modifier with preg_replace_callback to help me understand what's broken, but I think my issue is complicated by the javascript.

I'm hoping someone might be able to walk me through this, with respect to my code?

Thanks in advance.

Community
  • 1
  • 1
Troyd
  • 434
  • 5
  • 13

2 Answers2

1

The e modifier is in your first $out variable. To transform that, you need to use correctly preg_replace_callback():

$out = preg_replace_callback('/([ \t]*)(\[[^\]]+\][ \t]*\=\>[ \t]*[a-z0-9 \t_]+)\n[ \t]*\(/iU', "callbackFunction", $out);

function callbackFunction($matches) {
     return "'".$matches[1]."<a href=\"javascript:toggleDisplay(\''.(\$id = substr(md5(rand().'".$matches[0]."'), 0, 7)).'\');\">".$matches[2]."</a><div id=\"'.\$id.'\" style=\"display: none;\">'";
}

See that in preg_replace_callback we define second parameter with callbackFunction, that string is parsed to call that function and it passes an array with the matches. So the replacements were in callbackFunction() function and the matches are matches[X].

More info:

http://php.net/manual/es/function.preg-replace-callback.php

Good luck!

Mech
  • 3,952
  • 2
  • 14
  • 25
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
0

This is the combination of the original with Christian's fix.

function print_r_tree($data)
{
    // capture the output of print_r
    $out = print_r($data, true);

    // replace something like '[element] => <newline> (' with <a href="javascript:toggleDisplay('...');">...</a><div id="..." style="display: none;">
    $out = preg_replace_callback('/([ \t]*)(\[[^\]]+\][ \t]*\=\>[ \t]*[a-z0-9 \t_]+)\n[ \t]*\(/iU', 'print_r_tree_callback', $out);

    // replace ')' on its own on a new line (surrounded by whitespace is ok) with '</div>
    $out = preg_replace('/^\s*\)\s*$/m', '</div>', $out);

    // print the javascript function toggleDisplay() and then the transformed output
    return '<script language="Javascript">function toggleDisplay(id) { document.getElementById(id).style.display = (document.getElementById(id).style.display == "block") ? "none" : "block"; }</script>'."\n$out";
}

function print_r_tree_callback($matches) {
    $id = substr(md5(rand().$matches[0]), 0, 7);
    return "$matches[1]<a href=\"javascript:toggleDisplay('$id');\">$matches[2]</a><div id='$id' style=\"display: none;\">";
}