Php 通过引用转换变量替换文本中的占位符

Php 通过引用转换变量替换文本中的占位符,php,eval,preg-replace-callback,custom-function,variable-names,Php,Eval,Preg Replace Callback,Custom Function,Variable Names,我正在尝试从以下函数中删除eval。我尝试使用sprintf和${},但仍然找不到解决方案 以下是功能: function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){ $pippo='Pizza'; return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) { // $val=${trim($re

我正在尝试从以下函数中删除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);
}

伙计,你正在使用一些奇怪的Perl风格的代码。问题是PHP调用的双
$$
。一旦你修剪掉一个
$
它就可以工作了

<?php

function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
    $pippo='Pizza';
    return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
      $val=${substr(trim($res[1]), 1)}; // here trim the $ away from the matched string
      return isset($val) ? $val : $res[0];
    },$value);
}

echo parseDbString(); // prints "Looking for a good Pizza"

它在返回值后与我配合良好

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);

    return $value;
}
但若你们想让它更具动态性,你们可以使用它下面的函数,你们可以像['$pippo'=>'pizza']一样将$data作为数组传递,并在第二个参数中传递字符串

function parseDbString2($data , $string) {
    $parsed = preg_replace_callback('/{{(.*?)}}/', function ($matches) use ($data) {
        list($shortCode, $index) = $matches;

        if (isset($data[$index])) {
            return $data[$index];
        } else {
            throw new \Exception("Shortcode {$shortCode} not found ", 1);
        }
    }, $string);

    return $parsed;
}
希望它能帮助您

因此,是的,
eval()
经常被视为php中最高级的“邪恶”之一。在大多数情况下,当任务本身需要通过
eval()
或变量(基本上是包装不良的数组)来解决时,这是数据存储/声明不当的症状,通常最好的做法是彻底重新思考

为了在不从根本上重写自定义函数的情况下解决您的孤立问题,我将提供一个较小的“邪恶”(但在我看来仍然是“邪恶”,因为它的使用存在风险)
GLOBALS&
global

代码:()

输出:

Global: Pizza                    # <-- for demonstraton purposes
pippo                            # <-- for demonstraton purposes
Looking for a good Pizza         # <-- desired output
根据您对输入数据的控制程度,您现在可以删除输入字符串中
pippo
之前的
$
,从而消除一些不必要的字符

如果你还在阅读,你可以用
strtr()
str\u replace()
来清理这一切。()


用另一个分隔符替换
{{}
。 例如:

class Test {
  protected $item1 = 'I`m item-1';
  protected $item2 = 'I`m item-2';
  public function parseDbString($value = 'Looking for a good 1:$$item1 2:$$item2 5:$$item5 blabla'){
     $m = '';
     $result = $value;
     if( preg_match_all('~\$\$(.+?)\s~s', $value, $m)){
       foreach( $m[1] as $var ){
         if( property_exists( $this, $var )){
           $result = str_replace('$$' .$var, $this->{$var}, $result);
         } else {
           $result = str_replace('$$' .$var, 'UNDEFINED', $result);
         }
       }
     }
     return $result;
  }
}
$test = new Test();
var_dump( $test->parseDbString() );

“我想stru_replace不起作用了?”巴里说,它起作用了。我想知道的是为什么
$val=${trim($res[1])
不工作而不是计算任意变量,您能否构建变量名及其值的哈希,并使用该哈希解析字符串中的扩展?这样会更安全,也更容易调试;返回空($val)$res[0]:$val?什么是$res,你能把$res变为dump吗;有?$res是preg_replace的结果数组。不起作用。。。它返回
未定义变量:pippo
Hmm,适合我。虽然我使用的是PHP7,但您需要PHP7dude@Vixed那我就不知道问题出在哪里了。检查我在上面的评论中提供的链接,然后单击按钮ExecuteCode。它返回
寻找好的比萨饼
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();
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();
class Test {
  protected $item1 = 'I`m item-1';
  protected $item2 = 'I`m item-2';
  public function parseDbString($value = 'Looking for a good 1:$$item1 2:$$item2 5:$$item5 blabla'){
     $m = '';
     $result = $value;
     if( preg_match_all('~\$\$(.+?)\s~s', $value, $m)){
       foreach( $m[1] as $var ){
         if( property_exists( $this, $var )){
           $result = str_replace('$$' .$var, $this->{$var}, $result);
         } else {
           $result = str_replace('$$' .$var, 'UNDEFINED', $result);
         }
       }
     }
     return $result;
  }
}
$test = new Test();
var_dump( $test->parseDbString() );