Custom parsing function PHP

只愿长相守 提交于 2019-12-05 23:08:22

So, yes, eval() is often detested as one of the highest order "evils" in php. In most cases, when a task lends itself to be solved by eval() or variable-variables (which are basically poorly packaged arrays), this is a symptom of inappropriately stored/declared data and often the best course of action is a complete rethink.

To solve your isolated question without fundamentally rewriting the custom function, I'll offer a lesser "evil" (but still an "evil" in my opinion because there are risks in its usage) -- GLOBALS & global...

Code: (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();

Output:

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

...so why is this workaround a "bad idea", well, imagine you have a string that contains {{ $db }} -- such a common variable name is likely to exists in your list of global variables. So if the {{ variable }} in your string matches ANY of the variables in the global scope, you're going to get faulty outcomes.


Now, what should you do? Just declare your $pippo data in an array so that you have an associative relationship to leverage. (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();

Depending upon the amount of control you have over your input data, you can now afford to remove the $ before pippo in your input string -- which eliminates a few unnecessary characters here and there.

And if you are still reading, you can clean this whole thing up with strtr() or 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();

it work well with me after return value

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

but if you want it more dynamic you can use function below it you can pass $data as array like ['$pippo'=>'pizza'] and pass string in second parameter

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

hope it will help you

Man you're tapping into some weird Perl-ish style of code. The problem is the double $$ that gets called by PHP. Once you trim one $ away it works.

<?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"

Check the output of http://sandbox.onlinephpfunctions.com/code/86b3f37ac6c315d8e9a757c827455281df21fc89

Replace {{}} with another separator. For example:

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() );
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!