简体   繁体   English

关于PHP 5中的eval的问题

[英]Question about eval in PHP 5

I have been doing PHP stuff for almost one year and I have never used the function eval() though I know the usage of it. 我已经做了近一年的PHP东西,我从来没有使用函数eval()虽然我知道它的用法。 But I found many questions about it in SO.So can someone show me a simple example in which it's necessary to use eval() ?And is it a good or bad practice? 但是我在SO中发现了很多关于它的问题。所以有人能告诉我一个简单的例子,其中有必要使用eval()吗?这是一个好的还是坏的做法?

eval() is necessary to implement a "compiling" template engine, like Smarty, that uses its own language and compiles it down to php on the fly. eval()是实现像Smarty这样的“编译”模板引擎所必需的,它使用自己的语言并在运行时将其编译成php。 The main function of such engines is usually something like 这种引擎的主要功能通常是类似的

 function render_template($path) {
    $code = file_get_contents($path);
    $php = $this->compile_to_php($code);
    eval($php);
 }

Besides that, everytime you use "include" or "require", you're actually using "eval" under the hood - so, actually, eval is one of the mostly used php constructs. 除此之外,每次使用“include”或“require”时,你实际上都在使用“eval” - 所以,实际上,eval是最常用的php结构之一。

Using eval() is a bad practice, and if it turns out to be necessary to achieve something, that is usually the sign of a underlying design error. 使用eval()是一种不好的做法,如果事实证明是必要的,那通常是潜在设计错误的标志。

I can't think of any situation where it is necessary to use eval() . 我想不出有必要使用eval()的任何情况。 (ie something can't be achieved using other language constructs, or by fixing a broken design.) Interested to see whether any genuine cases come up here where eval actually is necessary or the alternative would be horribly complex. (即东西不能用其它语言结构,或通过固定一个破碎的设计来实现的。)有兴趣看到任何真正的情况是否来这里的eval地方实际需要或选择将是可怕的复杂。

The only instance of where it could be necessary is for executing code coming from an external source (eg database records.) But this is a design error in itself IMO. 可能需要的唯一实例是执行来自外部源的代码(例如数据库记录)。但这本身就是IMO的设计错误。

糟糕的应用程序设计总是这样的例子。

Well I have used eval once. 好吧,我曾经使用过eval一次。 This was for a system, where the users could enter formulas using constants fished from the underlying system. 这是一个系统,用户可以使用从底层系统中捕获的常量输入公式。

A string like: 字符串如:

(N * (G - 2,7)) / E

was taken and the constants replaced with values from the system eval is then used to get a value. 然后使用系统eval中的值替换常量来获取值。 eval seemed like the easiest way to go. eval似乎是最简单的方法。 The statement was filtered to only allow operators and uppercase letters(no two next to each other) so perhaps this is not a "real" use case of eval, but it works and is pretty readable. 该语句被过滤为仅允许运算符和大写字母(彼此没有两个),所以这可能不是eval的“真实”用例,但它可以工作并且非常易读。

That said the system in questing is huge (200k+ lines) and this is the only place that eval is used. 这就是说,任务系统是巨大的(200k +线),这是使用eval的唯一地方。

A command line php shell is a great example. 命令行php shell就是一个很好的例子。 I guess you could fork the actual php code and write your shell extensions in C instead, but it seems much more sensible to do it in php. 我想你可以分叉实际的PHP代码并在C中编写你的shell扩展,但在php中做它似乎更明智。 Since the person providing the code should already have full access to the system, there's no security issue at all. 由于提供代码的人应该已经拥有对系统的完全访问权限,因此根本没有安全问题。 Once you get php compiled with readline, this sort of thing is actually really useful. 一旦你用readline编译php,这种事实际上真的很有用。

Drupal (optionally) uses eval to allow for ready extensibility. Drupal(可选)使用eval来实现随时可扩展性。 To accomplish this it takes user (generally administrator-only) input of code to be evaluated and stores it in the database. 为实现此目的,需要评估用户(通常仅限管理员)的代码输入并将其存储在数据库中。 Drupal also has lots of people making sure that there are no security holes. Drupal还有很多人确保没有安全漏洞。

Eval useful for example in such case, as register widgets in cycle in wordpress while creating custom theme: Eval在这种情况下很有用,例如在创建自定义主题时在wordpress中循环注册小部件:

class PluginusNetWPTF_Widget extends PluginusNetWPTF_Core {

    public static $widgets = array(
        'PLUGINUSNET_RECENT_POSTS_WIDGET' => array(
            'description' => 'Recent posts of selected category',
            'creation' => 'PluginusNet Recent Posts',
            'fields' => array('title' => 'Recent Posts', 'category' => '', 'post_number' => 3, 'show_thumbnail' => 1, 'show_exerpt' => 0),
            'view' => 'recent_posts',
            'form' => 'recent_posts_form'
        ),
            //'PLUGINUSNET_RECENT_POSTS_WIDGET2' => array(),
    );

    public static function register_widgets() {
        foreach (self::$widgets as $widget_class_name => $widget_data) {
            $code = '

class '.$widget_class_name.' extends WP_Widget {

    //Widget Setup
    function __construct() {
        //Basic settings
        $settings = array("classname" => __CLASS__, "description" => __(PluginusNetWPTF_Widget::$widgets[__CLASS__]["description"], PLUGINUSNET_THEME_NAME));

        //Creation
        $this->WP_Widget(__CLASS__, __(PluginusNetWPTF_Widget::$widgets[__CLASS__]["creation"], PLUGINUSNET_THEME_NAME), $settings);
    }

    //Widget view
    function widget($args, $instance) {
        $args["instance"] = $instance;
        echo PluginusNetWPTF_Widget::draw_html("widget/" . PluginusNetWPTF_Widget::$widgets[__CLASS__]["view"], $args);
    }

    //Update widget
    function update($new_instance, $old_instance) {
        $instance = $old_instance;
        if (!empty(PluginusNetWPTF_Widget::$widgets[__CLASS__]["fields"])) {
            foreach (PluginusNetWPTF_Widget::$widgets[__CLASS__]["fields"] as $key => $value) {
                $instance[$key] = $new_instance[$key];
            }
        }

        return $instance;
    }

    //Widget form
    function form($instance) {
        //Defaults
        $defaults = PluginusNetWPTF_Widget::$widgets[__CLASS__]["fields"];
        $instance = wp_parse_args((array) $instance, $defaults);
        $args = array();
        $args["instance"] = $instance;
        $args["widget"] = $this;
        echo PluginusNetWPTF_Widget::draw_html("widget/" . PluginusNetWPTF_Widget::$widgets[__CLASS__]["form"], $args);
    }

}

';
            eval($code);
            register_widget($widget_class_name);
        }
    }

}

Using eval is quite dangerous, if see from security side. 如果从安全方面看,使用eval是非常危险的。 Anyway, a lot of template engines use eval, because they should parse page and get some variables or make calculations. 无论如何,很多模板引擎都使用eval,因为它们应该解析页面并获取一些变量或进行计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM