我正在尝试在互联网上部署我的网站,以便在真实环境中对其进行测试。它是某种文本编辑器,用户可以使用正则表达式和用户定义的回调函数。
我在preg_replace_callback()函数中遇到了一些问题。我的托管有早于5.3的PHP版本,我不能在我的代码中使用匿名函数(我在localhost上有PHP 5.4)。所以我必须重写这部分代码(在localhost上正常工作)
$newString = preg_replace_callback(
'#' . $this->pattern . '#' . $this->modifiers,
function($match)
{
return eval('return ' . $this->replacement . ';');
},
$string);
此时我并不是在谈论使用eval()的危险 - 稍后会对这个问题给予适当的关注(“禁止”单词列表检查等)。问题是我的尝试如下
$replacement = $this->replacement;
$newString = preg_replace_callback(
'#' . $this->pattern . '#' . $this->modifiers,
create_function('$match', '
global $replacement;
return eval(\'return \' . $replacement . \';\');
'),
$string);
不起作用且不会发生错误。我的代码出了什么问题?
非常感谢任何帮助。
新信息。我试过这个
Class A
{
public function check()
{
$string = 'series 3-4';
$pattern = 'series[ ]*(\d+)[ ]*-[ ]*(\d+)';
$modifiers = 'um';
$replacement = '$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"';
$newString = preg_replace_callback(
'#' . $pattern . '#' . $modifiers,
create_function('$match', '
global $replacement;
echo $replacement;
return eval(\'return \' . $replacement . \';\');
'),
$string);
echo $newString;
}
}
$a = new A;
$a->check();//get nothing
并发现create_function()内的$ replacement为空。但是当我在类$外使用相同的create_function()时,$ replacement不为空:
$string = 'series 3-4';
$pattern = 'series[ ]*(\d+)[ ]*-[ ]*(\d+)';
$modifiers = 'um';
$replacement = '$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"';
$newString = preg_replace_callback(
'#' . $pattern . '#' . $modifiers,
create_function('$match', '
global $replacement;
echo $replacement . "<br/>";
return eval(\'return \' . $replacement . \';\');
'),
$string);
echo $newString;
//$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"
//series 3 and 4
答案 0 :(得分:5)
您可以使用方法代替lambda函数:
Class A
{
private $replacement;
public function check()
{
$string = 'series 3-4';
$pattern = 'series[ ]*(\d+)[ ]*-[ ]*(\d+)';
$this->replacement = '$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"';
$modifiers = 'um';
$newString = preg_replace_callback(
'#' . $pattern . '#' . $modifiers,
array($this, 'replacementCallback'),
$string);
echo $newString;
}
private function replacementCallback($match)
{
return eval('return ' . $this->replacement . ';');
}
}
$a = new A;
$a->check();
答案 1 :(得分:1)
这样可行,将格式正确为PHP源的$replacement
字符串值插入函数源:
function check()
{
$string = 'series 3-4';
$pattern = 'series[ ]*(\d+)[ ]*-[ ]*(\d+)';
$modifiers = 'um';
$replacement = '$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"';
$newString = preg_replace_callback(
'#' . $pattern . '#' . $modifiers,
create_function('$match', '
return eval("return " . '.var_export($replacement,true).' . ";");
'),
$string);
echo $newString;
}
check(); // prints "series 3 and 4"
?>
但是当你可以直接把它放在函数的源代码中时,为什么还要放入代码和eval
呢:
<?
function check()
{
$string = 'series 3-4';
$pattern = 'series[ ]*(\d+)[ ]*-[ ]*(\d+)';
$modifiers = 'um';
$replacement = '$match[2] == $match[1] + 1 ? "series $match[1] and $match[2]" : "series $match[1]-$match[2]"';
$newString = preg_replace_callback(
'#' . $pattern . '#' . $modifiers,
create_function('$match', '
return '.$replacement.';
'),
$string);
echo $newString;
}
check(); // prints "series 3 and 4"
?>