[pmwiki-users] Recipes you use/need to be updated for PHP 5.5
Petko Yotov
5ko at 5ko.fr
Wed Jan 8 16:15:17 CST 2014
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
More information about the pmwiki-users
mailing list