如何在preg_replace_callback函数中访问变量?

16
我试图用传递的数组中的值替换$text中的{{key}}项,但是当我尝试添加print_r以查看发生了什么时,我得到了一个Undefined variable: kvPairs错误。如何从preg_replace_callback内部访问我的变量?
public function replaceValues($kvPairs, $text) {
    $text = preg_replace_callback(
        '/(\{{)(.*?)(\}})/',
        function ($match) {
            $attr = trim($match[2]);
            print_r($kvPairs[strtolower($attr)]);
            if (isset($kvPairs[strtolower($attr)])) {
                return "<span class='attr'>" . $kvPairs[strtolower($attr)] . "</span>";
            } else {
                return "<span class='attrUnknown'>" . $attr . "</span>";
            }
        },
        $text
    );
    return $text;
}

更新:

我尝试了使用全局作用域,但它也不起作用。我添加了两个打印语句来查看正在发生的情况,一个在 preg_replace_callback 内部,一个在外部。

public function replaceValues($kvPairs, $text) {
    $attrTest = 'date';
    print_r("--" . strtolower($attrTest) . "--" . $kvPairs[strtolower($attrTest)] . "--\n");
    $text = preg_replace_callback(
        '/(\{{)(.*?)(\}})/',
        function ($match) {
            global $kvPairs;
            $attr = trim($match[2]);
            print_r("==" . strtolower($attr) . "==" . $kvPairs[strtolower($attr)] . "==\n");
            if (isset($kvPairs[strtolower($attr)])) {
                return "<span class='attr'>" . $kvPairs[strtolower($attr)] . "</span>";
            } else {
                return "<span class='attrUnknown'>" . $attr . "</span>";
            }
        },
        $text
    );
    return $text;
}
我收到的输出是:
--date--1977-05-20--
==date====
2个回答

50

由于您的回调函数是闭包,因此您可以通过use传递额外的参数。

function ($match) use ($kvPairs) {
    ...
}

比污染全球空间更好


我想操作$kvPairs以供下一个匹配使用,这是否可行或者我需要一个全局变量来实现? - Wikunia
8
如果您需要在回调函数中操作$kvPairs,则需要通过___引用传递___:function ($match) use (&$kvPairs) { ... } - Mark Baker

0

您的脚本可以进行现代化和精细化改进,以允许访问全局作用域值而无需使用use()。PHP7.4中的箭头函数语法允许访问在回调范围之外声明的变量。

我已经从您的模式中删除了一些不必要的转义和捕获组。在捕获组的两侧添加一些占用空间的逻辑可以省略对捕获字符串的trim()调用。

代码:(演示

function replaceValues(array $kvPairs, string $text): string
{
    return preg_replace_callback(
               '/{{\s*(.*?)\s*}}/',
                fn($m) => isset($kvPairs[strtolower($m[1])])
                    ? '<span class="attr">' . $kvPairs[strtolower($m[1])] . '</span>'
                    : '<span class="attrUnknown">' . $m[1] . '</span>',
                $text
            );
}

否则,这就是 使用在其外部计算的变量的回调函数 的副本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接