回调函数和变量作用域 - preg_replace_callback

时间:2018-03-27 18:44:33

标签: php regex preg-replace preg-replace-callback

使用e修饰符升级旧的PHP代码,其中有几个替换调用。

$content = "Some {{language}} to be replaced.";
$array = ("language" => "text", ......, "someother" => "variables");
extract($array);
$content = preg_replace("/\{\{(.*?)\}\}/e", "$$1", $content);

是否可以以类似的方式使用preg_replace_callback或更好的解决方案?

使用回调函数,$array的提取变量超出了函数范围。

更新

也许不是最好的解决方案,但它对我来说效果很好:

preg_match_all('/\{\{(.*?)\}\}/', $content, $matches);

foreach ($matches[0] as $index => $var_name) {
    if (isset(${$matches[1][$index]})) {
        $tmp_var_name = trim($var_name, '{}');
        $content = str_replace($var_name, $$tmp_var_name, $content);
    }
}

更新#2 这是我能想到的最好的。我没有通过几个文件来查找所有变量,而是制作了一个临时数组并在回调中使用它。

//match all and build array of variables
$build_array = array();
preg_match_all('/<{(.*?)}>/', $out1, $matches);
foreach ($matches[0] as $index => $var_name) {
    $tmp_var_name = $matches[1][$index];
    if (isset($$tmp_var_name)) {
       $build_array[$tmp_var_name] = $$tmp_var_name;
    } else {
        $build_array[$tmp_var_name] = '';
    }
}
//use new array and replace
$string .= preg_replace_callback("/<{(.*?)}>/",
                     function($m) use($build_array) { return $build_array[$m[1]]; },
                     $out1);

1 个答案:

答案 0 :(得分:0)

要使$array在函数中可用,请使用use导入它:

$content = preg_replace_callback("/\{\{(.*?)\}\}/",
                                 function($m) use($array) { return $array[$m[1]]; },
                                 $content);

要使用从extract创建的全局变量,只需访问$GLOBALS Superglobal数组:

$content = preg_replace_callback("/\{\{(.*?)\}\}/",
                                 function($m) { return $GLOBALS[$m[1]]; },
                                 $content);

显然,如果extract没有在全球范围内完成,那么这不会起作用。然后,您唯一的选择是确定哪些数组创建提取的变量,然后将其导入函数。

但是,考虑到要替换的现有应用程序,代码和值,只需:

foreach($GLOBALS as $key => $value) {
    $content = str_replace('{{'.$key.'}}', $value, $content);
}

如果在调用extract的函数中完成此操作,请获取已定义的变量:

foreach(get_defined_vars() as $key => $value) {
    $content = str_replace('{{'.$key.'}}', $value, $content);
}