I just updated PHP on my server from php 5 to php 7 and I'm getting these warnings:
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(0x\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(0x\1)', to be a valid callback
This is the PHP code:
private function _decode( $source )
{
$source = html_entity_decode($source, ENT_QUOTES, 'UTF-8');
$source = preg_replace_callback('/&#(\d+);/me',"chr(\\1)", $source);
$source = preg_replace_callback('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);
return $source;
}
The Warning is come from:
$source = preg_replace_callback('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);
How i can fix this?
The /e modifier (PREG_REPLACE_EVAL) is no longer supported, as noted in the PHP 7.0 migration guide. You need to use a callable function, not a string that will be evaluated as a function. In your case, replace your string function -- chr(0x\\1) -- with a Closure:
$source = preg_replace_callback(
'/&#x([a-f0-9]+);/mi',
fn($m) => chr(hexdec('0x'.$m[1])),
$source
);
The inline string replacement of \\1 to yield a valid PHP hexadecimal, like 0x21, no longer works that way in the callable: you need a hexdec call to accomplish the same.
See it in action on 3v4l.org.
If you do not yet have PHP 7.4 with short closures, you need to write that as:
$source = preg_replace_callback(
'/&#x([a-f0-9]+);/mi',
function ($m) { return chr(hexdec('0x'.$m[1])); }, // Now a Closure
$source
);
Related
I just updated PHP on my server from php 5 to php 7 and I'm getting these warnings:
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(0x\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(\1)', to be a valid callback
Warning: preg_replace_callback() [function.preg-replace-callback0]: Requires argument 2, 'chr(0x\1)', to be a valid callback
This is the PHP code:
private function _decode( $source )
{
$source = html_entity_decode($source, ENT_QUOTES, 'UTF-8');
$source = preg_replace_callback('/&#(\d+);/me',"chr(\\1)", $source);
$source = preg_replace_callback('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);
return $source;
}
The Warning is come from:
$source = preg_replace_callback('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);
How i can fix this?
The /e modifier (PREG_REPLACE_EVAL) is no longer supported, as noted in the PHP 7.0 migration guide. You need to use a callable function, not a string that will be evaluated as a function. In your case, replace your string function -- chr(0x\\1) -- with a Closure:
$source = preg_replace_callback(
'/&#x([a-f0-9]+);/mi',
fn($m) => chr(hexdec('0x'.$m[1])),
$source
);
The inline string replacement of \\1 to yield a valid PHP hexadecimal, like 0x21, no longer works that way in the callable: you need a hexdec call to accomplish the same.
See it in action on 3v4l.org.
If you do not yet have PHP 7.4 with short closures, you need to write that as:
$source = preg_replace_callback(
'/&#x([a-f0-9]+);/mi',
function ($m) { return chr(hexdec('0x'.$m[1])); }, // Now a Closure
$source
);
I am using preg_replace() to replace {#page} with the actual value of the variable $page. Of course I have a lot of {#variable}, not just {#page}.
For example:
$uri = "module/page/{#page}";
$page = 3;
//preg_replace that its working now
$uri_to_call = $uri_rule = preg_replace('/\{\#([A-Za-z_]+)\}/e', "$$1", $uri);
And I get the result
"module/page/3";
After update to PHP 5.4 i get the error:
Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead
And I don't know how to rewrite the preg_replace() with preg_replace_callback().
I have try to follow the answer from SO Replace preg_replace() e modifier with preg_replace_callback
Like this:
public static function replace_vars($uri) { //$uri_rule = preg_replace('/\{\#([A-Za-z_]+)\}/e', "$$1", $uri);
return preg_replace_callback('/{\#([A-Za-z_]+)\}/',
create_function ('$matches', 'return $$matches[1];'), $uri);
}
But I also get a warning:
Notice: Undefined variable: page
Which is actually true because page variable it's not set runtime-created function.
Can anyone help me?
Your problem is as you already know, that your variables are out of scope in your anonymous functions and since you don't know which one you will replace you can't pass them to the function, so you have to use the global keyword, e.g.
$uri = "module/page/{#page}";
$page = 3;
$uri_to_call = $uri_rule = preg_replace_callback("/\{\#([A-Za-z_]+)\}/", function($m){
global ${$m[1]};
return ${$m[1]};
});
I have this line of code:
$from_uk_name = preg_replace("/^_/", "", preg_replace("/([A-Z]{1})/e", "'_'.strtolower($property_name[1])", $from_name))
But since I move the server to PHP 5.5.22 and preg_replace() is deprecated I need to move that line into preg_replace_callback() but has not idea since there are nested preg_replace calls, can I get some advice?
As from the comments requested:
This should work for you:
$from_uk_name = preg_replace("/^_/", "",
preg_replace_callback("/([A-Z]{1})/", function($m){
return "'_'" . strtolower($m[1]);
}, $from_name));
I need a little help. Because preg_replace is deprecated, I have to convert all my preg_replace to preg_replace_callback...
What I've tried:
Change:
$template = preg_replace ( "#\\[aviable=(.+?)\\](.*?)\\[/aviable\\]#ies", "\$this->check_module('\\1', '\\2')", $template );
To:
$template = preg_replace_callback ( "#\\[aviable=(.+?)\\](.*?)\\[/aviable\\]#isu",
return $this->check_module($this['1'], $this['2']);
$template );
Error:
Parse error: syntax error, unexpected 'return'
The callback needs to be a function taking one parameter which is an array of matches. You can pass any kind of callback, including an anonymous function.
$template = preg_replace_callback(
"#\\[aviable=(.+?)\\](.*?)\\[/aviable\\]#isu",
function($matches) {
return $this->check_module($matches[1], $matches[2]);
},
$template
);
(PHP >= 5.4.0 required in order to use $this inside the anonymous function)
I would like to know if there is a simple way to use the matched pattern in a preg_replace as an index for the replacement value array.
e.g.
preg_replace("/\{[a-z_]*\}/i", "{$data_array[\1]}", $string);
Search for {xxx} and replace it with the value in $data_array['xxx'], where xxx is a pattern.
But this expression does not work as its invalid php.
I have written the following function, but I'd like to know if it is possible to do it simply. I could use a callback, but how would I pass the $data_array to it too?
function mailmerge($string, $data_array, $tags='{}')
{
$tag_start=$tags[0];
$tag_end =$tags[1];
if( (!stristr($string, $tag_start)) && (!stristr($string, $tag_end)) ) return $string;
while(list($key,$value)=each($data_array))
{
$patterns[$key]="/".preg_quote($tag_start.$key.$tag_end)."/";
}
ksort($patterns);
ksort($data_array);
return preg_replace($patterns, $data_array, $string);
}
From my head:
preg_replace_callback("/\{([a-z_]*)\}/i", function($m) use($data_array){
return $data_array[$m[1]];
}, $string);
Note: The above function requires PHP 5.3+.
Associative Array replacement - keep matched fragments if not found:
$words=array("_saudation_"=>"Hello", "_animal_"=>"cat", "_animal_sound_"=>"MEooow");
$source=" _saudation_! My Animal is a _animal_ and it says _animal_sound_ , _no_match_";
echo (preg_replace_callback("/\b_(\w*)_\b/", function($match) use ($words) { if(isset($words[$match[0]])){
return ($words[$match[0]]);}else{
return($match[0]);}
}, $source));
//returns: Hello! My Animal is a cat and it says MEooow , _no_match_
*Notice, thats although "_no_match_" lacks translation, it will match during regex, but
preserve its key.
you can use preg_replace_callback and write a function where you can use that array index, or else you can use the e modifier to evaluate the replacement string (though note that the e modifier is deprecated, so the callback function is better solution).