编程语言
首页 > 编程语言> > 自定义解析函数PHP

自定义解析函数PHP

作者:互联网

我正在尝试从以下函数中删除eval.我尝试使用sprintf和${},但仍无法找到解决方案.

这里的功能:

function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
    $pippo='Pizza';
    return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
      // $val=${trim($res[1])}; Returns "Undefined variable: $pippo"
      $val=@eval("return ".trim($res[1]).";"); // Returns "Looking for a good Pizza"
      return isset($val) ? $val : $res[0];
    },$value);
}

解决方法:

所以,是的,eval()通常被认为是php中最高级别的“邪恶”之一.在大多数情况下,当一个任务有助于通过eval()或变量(基本上是打包得很差的数组)来解决时,这是一个不恰当存储/声明的数据的症状,通常最好的行动方案是一个完整的反思.

为了解决你的孤立问题而不从根本上重写自定义函数,我会提供一个较小的“邪恶”(但在我看来仍然是“邪恶”,因为它的使用存在风险) – GLOBALS&全球…

代码:(Demo)

function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
    global $pippo;                        // declare $pippo as a global variable
    $pippo = 'Pizza';
    return preg_replace_callback('/{{ \$(.*?) }}/', function($m) use ($pippo) {
        echo "Global: " , $GLOBALS['pippo'];
        echo "\n{$m[1]}\n";
        return $GLOBALS[$m[1]] ?? $m[0];  // null coalescing operator provides fallback
    },$value);
}
echo parseDbString();

输出:

Global: Pizza                    # <-- for demonstraton purposes
pippo                            # <-- for demonstraton purposes
Looking for a good Pizza         # <-- desired output

…为什么这个解决方法是一个“坏主意”,好吧,想象你有一个包含{{$db}}的字符串 – 这样一个公共变量名可能存在于你的全局变量列表中.因此,如果字符串中的{{variable}}与全局范围中的任何变量匹配,那么您将得到错误的结果.

现在,你应该怎么做?只需在数组中声明您的$pippo数据,这样就可以使用关联关系. (Demo)

function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
    $lookup = ['pippo' => 'Pizza'];
    return preg_replace_callback('/{{ \$(.*?) }}/', function($m) use ($lookup) {
        return $lookup[$m[1]] ?? $m[0];  // null coalescing operator provides fallback
    }, $value);
}
echo parseDbString();

根据您对输入数据的控制量,您现在可以在输入字符串中删除$pippo之前 – 这样可以消除一些不必要的字符.

如果你还在阅读,你可以使用strtr()或str_replace()来清理整个事情. (Demo)

function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
    $lookup = ['{{ $pippo }}' => 'Pizza'];  // this can be extended all you like!
    return strtr($value, $lookup);
}
echo parseDbString();

标签:variable-names,php,eval,preg-replace-callback,custom-function
来源: https://codeday.me/bug/20190727/1549196.html