【问题标题】:Converting preg_replace to preg_replace_callback for finding and replacing words with variables将 preg_replace 转换为 preg_replace_callback 以使用变量查找和替换单词
【发布时间】:2018-12-20 17:47:28
【问题描述】:

我有以下代码行:

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

这会将两个大括号括起来的单词替换为同名变量。即 {{username}} 被 $username 替换。

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

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

非常感谢任何帮助。

【问题讨论】:

  • $match[1] 用于包含您的变量名称的第一个捕获组。
  • 附带说明,这个error_log($match[0]) 似乎是用来调试的。你可以学习使用 xdebug (xdebug.org)。调试起来比这简单得多。
  • 我认为这里的主要问题是您引用的变量不会存在于函数的范围内。即,如果你有{{username}},那么$username 在函数中是未定义的。您可以将它们全部放在一个关联数组中,然后通过use 语句使该数组可用。这样,您实际上也建立了一个允许变量的白名单,所以像 {{this}} 这样的东西不会被利用。

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


【解决方案1】:

函数在 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__

【讨论】:

  • 理智的建议使用数组++
猜你喜欢
  • 1970-01-01
  • 2015-08-09
  • 2016-05-18
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多