Forums

Unfortunately no one can be told what FluxBB is - you have to see it for yourself.

You are not logged in.

#1 2013-04-09 09:17:24

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

preg_replace and pattern modifier e

Hi,

With PHP 5.5 :
e (PREG_REPLACE_EVAL)
    Warning
    This feature has been DEPRECATED as of PHP 5.5.0. Relying on this feature is highly discouraged.

Many preg_replace in parser.php use the pattern modifier e.

Have you studied how to replace it?


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#2 2013-04-09 11:26:56

Franz
Lead developer
From: Germany
Registered: 2008-05-13
Posts: 6,728
Website

Re: preg_replace and pattern modifier e

Isn't there a preg_replace_callback() method somewhere?


fluxbb.de | develoPHP

"As code is more often read than written it's really important to write clean code."

Offline

#3 2013-04-09 13:07:35

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

Of course! Php.net site itself tells to replace by "preg_replace_callback" with one or two examples. I'll look at it more closely, quite to test locally.


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#4 2013-04-09 13:20:15

Franz
Lead developer
From: Germany
Registered: 2008-05-13
Posts: 6,728
Website

Re: preg_replace and pattern modifier e

Would be cool if you have a few suggestions. smile

Thanks for the heads-up.


fluxbb.de | develoPHP

"As code is more often read than written it's really important to write clean code."

Offline

#5 2013-04-09 15:42:21

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

It is not as simple as it might seem at first sight. This may be because I wanted to start with something complicated. I will study quietly, I have time.
One of my former instructors - in the 60s - said: « It is going slowly we'll fastest. ». In French : « C'est en allant doucement qu'on va le plus vite ».


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#6 2013-04-10 16:22:12

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

Relatively simple to replace a "preg_replace" with pattern modifier "e" on one string by "preg_replace_callback".
For example, to treat citations in parser.php there is:

$text = preg_replace('%\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]%se', '"</p><div class=\"quotebox\"><cite>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), \'$2\')." ".$lang_common[\'wrote\']."</cite><blockquote><div><p>"', $text);

replaced by:

//[modif oto] for PHP 5.5.0 - Replacement of preg_replace and pattern modifier "e" with preg_replace_callback
$callback = function ($matches) {
	global $lang_common; 
	return "</p><div class=\"quotebox\"><cite>".str_replace(array('[', '\\"'), array('&#91;', '"'), $matches[2])." ".$lang_common['wrote']."</cite><blockquote><div><p>";
	};
$text = preg_replace_callback('%\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]%s', $callback, $text);

But I have not yet found the algorithms when dealing with arrays of "pattern" and "replace" and with "callback" functions different.
I cogitate...


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#7 2013-04-10 16:37:45

Franz
Lead developer
From: Germany
Registered: 2008-05-13
Posts: 6,728
Website

Re: preg_replace and pattern modifier e

Looks like a good start. smile

Please note that we cannot use closures (the function() { } statement), since they were added in PHP 5.3. Things like create_function() should help in that case, though.

I created a ticket for this.


fluxbb.de | develoPHP

"As code is more often read than written it's really important to write clean code."

Offline

#8 2013-04-10 17:40:28

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

With create_function :

//[modif oto] for PHP 5.5.0 - Replacement of preg_replace and pattern modifier "e" with preg_replace_callback
$callback = create_function ('$matches',
	'global $lang_common;
	return "</p><div class=\"quotebox\"><cite>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), $matches[2])." ".$lang_common[\'wrote\']."</cite><blockquote><div><p>";'
	);
$text = preg_replace_callback('%\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]%s', $callback, $text);

It's better (for me) than closures, because it seems that only the use of regex variables in "replace"(\'$2\') must be replaced by $matches[2] (And so on), and this greatly simplifies the treatment of $replace array.

Last edited by Otomatic (2013-04-10 17:41:16)


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#9 2013-04-11 15:18:10

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

When "preg_replace" uses simple strings (not arrays), it is relatively easy to transform into "function preg_replace_callback."
This becomes more complex with the use of arrays for research patterns and replacement, as only a part of the rules of research may have the modifier "e".
However, I think I have found a way to do it: separating items with modifier "e" to treat them separately.
For example, in the file "parser.php" in the function "do_bbcode", there is a treatment by "preg_replace" for a large number of rules, many of which have the modifier "e". And many rules are added with the use of BBcode bars as FluxToolbar.

The initial code is (lines 833-839):

	$replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\')';
	$replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\', \'$2\')';

	// This thing takes a while! :)
	$text = preg_replace($pattern, $replace, $text);

	return $text;

I replace it by:

	$replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\')';
	$replace[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=$1\', \'$2\')';

	// This thing takes a while! :)
	//$text = preg_replace($pattern, $replace, $text);
	// This thing takes a while and may be another while!
	//[modif oto] for PHP 5.5.0 - Replacement of preg_replace and pattern modifier "e" with preg_replace_callback
	//Separate patterns with "e" modifier and without
	$pattern_normal = $replace_normal = array();
	for($i = 0; $i < count($pattern) ; $i++)
	{
		if(substr($pattern[$i],-1) == "e")
		{
			$temp = str_replace(array('\'$1$3\'','\'$2$4\'','\'$1\'', '\'$2\'', '$1', '$2'), array('$matches[1].$matches[3]','$matches[2].$matches[4]','$matches[1]','$matches[2]','$matches[1]','$matches[2]'), $replace[$i]);
			$text = preg_replace_callback(substr($pattern[$i],0,-1), create_function('$matches','return '.$temp.';'), $text);
		}
		else
		{
			$pattern_normal[] = $pattern[$i];
			$replace_normal[] = $replace[$i];
		}
	}
	$text = preg_replace($pattern_normal, $replace_normal, $text);
	//[modif oto] - end

	return $text;

Last edited by Otomatic (2013-04-11 16:29:39)


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

#10 2013-04-12 14:37:22

Otomatic
FluxBB Donor
From: Paris - France
Registered: 2010-01-26
Posts: 576
Website

Re: preg_replace and pattern modifier e

Hi,

Personally, I prefer the alternative that performs only very few changes in the scripts where it will need to replace "preg_replace" with "preg_replace_callback," and only if you are using PHP 5.5.x.

I add two new functions in the file include/functions.php:

//[modif oto] for PHP 5.5.0 - Replacement of preg_replace and pattern modifier "e" with preg_replace_callback
function php55_callback($element)
{
	return str_replace(
		array('\'$1$3\'','\'$2$4\'','\'$1\'', '\'$2\'', '$1', '$2'),
		array('$matches[1].$matches[3]','$matches[2].$matches[4]','$matches[1]','$matches[2]','$matches[1]','$matches[2]'),
		$element);
}

//Separate patterns with "e" modifier and without
function php55_preg_replace($pattern, $replace, $text)
{
	//if not PHP 5.5.x no changes
	if(version_compare(PHP_VERSION, '5.5.0', '<'))
		return preg_replace($pattern, $replace, $text);

	if(!is_array($pattern)) {
		$pattern = array($pattern);
		$replace = array($replace);
	}
	$count = count($pattern);
	$pattern_normal = $replace_normal = array();
	for($i = 0; $i < $count ; $i++)
	{
		if(substr($pattern[$i],-1) == "e")
			$text = preg_replace_callback(substr($pattern[$i],0,-1), create_function('$matches','return '.php55_callback($replace[$i]).';'), $text);
		else
		{
			$pattern_normal[] = $pattern[$i];
			$replace_normal[] = $replace[$i];
		}
	}
	return preg_replace($pattern_normal, $replace_normal, $text);
}

Then it will only be necessary to change only the calls "preg_replace" who need it to "php55_preg_replace."


Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Ghandi
An error does not become truth by reason of multiplied propagation. Ghandi

Offline

Board footer

Powered by FluxBB