Вопрос по eval в PHP 5 - PullRequest
       33

Вопрос по eval в PHP 5

2 голосов
/ 20 марта 2010

Я занимаюсь PHP почти год и никогда не использовал функцию eval(), хотя знаю, как ее использовать. Но я нашел много вопросов об этом в SO.Так кто-то может показать мне простой пример, в котором необходимо использовать eval()? И это хорошая или плохая практика?

Ответы [ 7 ]

10 голосов
/ 20 марта 2010

eval () необходим для реализации механизма компиляции шаблонов, такого как Smarty, который использует свой собственный язык и компилирует его в php на лету. Основная функция таких двигателей обычно что-то вроде

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

Кроме того, каждый раз, когда вы используете «include» или «require», вы фактически используете «eval» под капотом - так, фактически, eval является одной из наиболее часто используемых конструкций php.

6 голосов
/ 20 марта 2010

Использование eval() является плохой практикой, и, если оказывается необходимым что-то достичь, это обычно является признаком основной ошибки проектирования.

Я не могу вспомнить ни одной ситуации, когда необходимо использовать eval(). (т.е. что-то не может быть достигнуто с помощью других языковых конструкций или путем исправления неработающей конструкции.) Интересно узнать, возникают ли какие-либо подлинные случаи, когда eval фактически является необходимым, или альтернатива будет ужасно сложной.

Единственный случай, когда это может быть необходимо, - это выполнение кода, поступающего из внешнего источника (например, записей базы данных). Но это ошибка проектирования сама по себе IMO.

4 голосов
/ 20 марта 2010

Ну, я однажды использовал eval.Это было для системы, где пользователи могли вводить формулы, используя константы, полученные из базовой системы.

Строка типа:

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

была взята, и константы, замененные значениями из системного eval, затем используются для получения значения.Эвал казался самым простым способом.Оператор был отфильтрован, чтобы разрешать только операторы и заглавные буквы (не две рядом друг с другом), поэтому, возможно, это не «реальный» вариант использования eval, но он работает и довольно читабелен.система в квестах огромна (200 тыс. + линий), и это единственное место, где используется eval.

4 голосов
/ 20 марта 2010

Плохой дизайн приложения - всегда такой пример.

3 голосов
/ 26 марта 2010

Отличным примером является командная строка php shell. Я думаю, что вы могли бы раскошелиться на настоящий php-код и вместо этого написать свои расширения оболочки на C, но кажется, что гораздо разумнее сделать это на php. Поскольку лицо, предоставляющее код, уже должно иметь полный доступ к системе, проблем с безопасностью нет вообще. Когда вы скомпилируете php с readline, такие вещи действительно будут полезны.

Drupal (опционально) использует eval, чтобы обеспечить готовность к расширению. Для этого требуется пользовательский (обычно только для администратора) ввод кода, который нужно оценить, и его сохранение в базе данных. В Drupal также много людей, которые следят за тем, чтобы не было дыр в безопасности.

2 голосов
/ 01 октября 2012

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

}
2 голосов
/ 20 марта 2010

Использование eval довольно опасно, если смотреть со стороны безопасности. В любом случае, многие движки шаблонов используют eval, потому что они должны анализировать страницу и получать некоторые переменные или делать вычисления.

...