将preg_replace转换为preg_replace_callback,以查找单词并将其替换为变量

问题描述 投票:0回答:1

我有以下代码行:

$message = preg_replace('/\{\{([a-zA-Z_-]+)\}\}/e', "$$1", $body);

这将两个大括号包围的单词替换为相同名称的变量。即{{username}}被$ username代替。

我正在尝试将其转换为使用preg_replace_callback。到目前为止,这是我基于Googling的代码,但我不确定自己在做什么! error_log输出显示变量名称,包括大括号。

$message = preg_replace_callback(
    "/\{\{([a-zA-Z_-]+)\}\}/",
        function($match){
            error_log($match[0]);
            return $$match[0];
        },
        $body
);

非常感谢任何帮助。

php regex preg-replace preg-replace-callback
1个回答
2
投票

函数在PHP中具有自己的变量范围,因此,除非您明确指定,否则要替换的任何内容在函数内部均不可用。我建议您将替换项放置在数组中,而不要放在单个变量中。这有两个优点-首先,它使您可以轻松地将它们放入函数范围内;其次,它提供了内置的白名单机制,因此您的模板不会偶然(或故意)引用不应被引用的变量。暴露。

// Don't do this:
$foo = 'FOO';
$bar = 'BAR';

// Instead do this:
$replacements = [
    'foo' => 'FOO',
    'bar' => 'BAR',
];

// Now, only things inside the $replacements array can be replaced.

$template = 'this {{foo}} is a {{bar}} and here is {{baz}}';
$message = preg_replace_callback(
    '/\{\{([a-zA-Z_-]+)\}\}/',
    function($match) use ($replacements) {
        return $replacements[$match[1]] ?? '__ERROR__';
    },
    $template
);

echo "$message\n";

这产生了:

this FOO is a BAR and here is __ERROR__
© www.soinside.com 2019 - 2024. All rights reserved.