从数据库记录运行php脚本而不使用eval()

时间:2014-12-05 13:14:39

标签: php mysql parsing eval

我想知道如何在不使用eval()的情况下运行存储在数据库中的php脚本。

预期流程如下

  

当用户POST一个包含{{ typed_alias }}的字符串时,系统将在表中搜索该别名是否在alias列中有记录。< / p>      

如果是的话 - &gt;将用户输入的内容替换为存储在replacement列中的相应脚本。

     

如果不是 - &gt;显示原始字符串,包括{{ wrong_alias }}

预期结果如下

  

用户发帖时
  您好,{{morninggg}},当前的unix时间为{{nowTime}}

     

数据库输出

     

阵列

 0 =>
   array
     'ID' => 445
     'alias' => 'morning'
     'replacement' => 'Good morning'
 1 =>
   array
     'ID' => 446
     'alias' => 'nowTime'
     'replacement' => time()
 2 =>
   array
     'ID' => 447
     'alias' => 'tommorowNow'
     'replacement' => time()+86400
     

返回

     

您好,{{morninggg}},当前的unix时间是147855220

现在我已经使用foreach解决了数据库数组,并且可以使用str_replace()替换脚本中的别名。

当前classI用于从数据库中获取数据并进行替换,如下所示

class replace {
    public $definitions;

    public function setDefinitions($definitions) {
        $this->definitions = $definitions;
    }

    public function tag($input) {
        if($this->definitions && is_array($this->definitions)) {
            foreach ($this->definitions as $definition) {
                if($defintion['alias'] == 'time') {
                    $input = str_replace('{{' . $definition['alias'] . '}}', date('Y-m-d'), $input);
                } else {
                    $input = str_replace('{{' . $definition['alias'] . '}}', $definition['replacement'], $input);
                }
            }
        }
        return $input;
    }
}

当前使用方法

$replace = new replace();
$replace->setDefinitions($tagEngine);
$parsedString = $replace->tag($__input);

//$__input is what user POST to the server

echo $parsedString;

但是,目前的结果如下

  

您好,{{morninggg}},当前的unix时间是时间()

无法在页面上成功运行脚本

但是当我像这样手动给出定义时

  

$definition = array('morning' => 'Good Morning', 'nowTime' => time()); foreach ($definition as $key => $value) $source = str_replace('{{' . $key . '}}', $value, $source); return $source;

该脚本可以运行并返回

  

您好,{{morninggg}},当前的unix时间是147855220

我知道使用eval()可以运行脚本,但是,在人们的实际应用程序中,它被认为是一种危险的方法。

有人可以给我一些关于如何处理这个问题的建议吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您不应使用eval()之类的功能来解决此问题。您应该从数据库中提取所有php代码并按如下方式解析不同的别名(我刚刚更改了tag()类中的replace方法:

public function tag($input) {
    if($this->definitions && is_array($this->definitions)) {
        foreach ($this->definitions as $definition) {
            $replacement = $definition['replacement'];
            switch($definition['alias']) {
                case 'nowTime':
                    $replacement = date('Y-m-d');
                    break;
                case 'tommorowNow':
                    $replacement = date('Y-m-d', (time() + 86400));
                    break;
            }
            $input = str_replace('{{' . $definition['alias'] . '}}', $replacement, $input);
        }
    }
    return $input;
}

如您所见,对于每个php-code别名,您可以在case语句中添加另一个switch()。您可以通过以下链接阅读switch()控制结构:

  

PHP: switch - Manual