John Rankin writes:
On 8/01/14 12:31 PM, Petko Yotov wrote:
Currently the PmWiki core does not restrict you at all to use closures in your recipes. You can have them, they will only work on PHP 5.3+ sites.
That works for me :-)

However, some advice on how best to convert the following case would be helpful. I use some code to extract the text of a link in the form:

$LinkTidy = array("/reg-exp1/" =>
     "MakeLink(\$pagename, ... matches ... , '\$LinkText')",
                  "/reg-exp2/" =>
     "MakeLink(\$pagename, ... matches ... ,  '\$LinkText')");
foreach ($LinkTidy as $exp => $repl) {
    $text = SomeFunction($exp, $repl, $text);
}

Currently, SomeFunction is preg_replace, $exp has an e modifier and matches contains '$1', '$2', etc as appropriate to the $exp. In some cases, $exp has no modifier and $repl is simply '$1'.

What is the best way to convert this? Preferably without a major code re- write, as I use this construct in several places.

For PHP 5.5 you need to create callback functions where your replacement requires evaluation.

And, you need to pass the $pagename value to the callback function.

Here is how I would try this:

 $LinkTidy = array(
"/pattern1/" => PCCF("return MakeLink('$pagename', \$m[1], ..., '\$LinkText');"), # evaluated: callback, but no /e
   "/pattern2/" => '<em>$0</em>', # not evaluated: string
 );
 $text = PPRA($LinkTidy, $text);

This will work with PHP 4.2 to 5.5.

The function PPRA($array, $text) where $array is array('search'=>'replace') and $text is the haystack, performs a regular expression search and replace. If the 'replace' part is a callback or any function name, it uses preg_replace_callback(), otherwise preg_replace().

The function PCCF("PHP code here") lets you create a callback lambda($m) where $m is the array of matches. The argument is the PHP code.

Two changes from your pre-PHP5.5 way:

1. Instead of '$0', '$1', '$2', '$3' ... we have $m[0], $m[1], $m[2], $m[3], no single quotes, and as we don't want to expand them when we declare the callback, we precede them with backslash: \$m[0], \$m[1], \$m[2], \$m[3].

2. $pagename is not in the scope of the callback function, so we don't prefix it with \ and we wrap it in single quotes :

 "return MakeLink('$pagename',...);"

this will expand $pagename and its "value" will be written as a string into the callback. This assumes that at the moment when you define the callback you know the value of $pagename, like in your example.

Read the function PCCF(), you can define custom callback templates and thus write less code.

Petko


_______________________________________________
pmwiki-users mailing list
pmwiki-users@pmichaud.com
http://www.pmichaud.com/mailman/listinfo/pmwiki-users

Reply via email to