2010-03-20 1 views
2

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

ответ

6

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

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

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

+1

разбор выражений, для одного. Хотя это редкость, мне приходилось делать это несколько раз. Конечно, это сложные и полные выражения, а не рутинная математика с поддержкой почти круглой скобки. Тем не менее, обычные меры предосторожности на eval всегда применяются: они медленные (исправлены с результатами кэширования), возможно, не нужны (не в моем случае) и проблемы с безопасностью (соответствующий код, однако, управляется самими системными администраторами, вопрос). – Christian

4

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

4

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

Строка типа: была взята

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

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

Это говорит о том, что система в поисках огромна (200k + lines), и это единственное место, где используется eval.

10

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

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

Помимо этого, каждый раз, когда вы используете «включить» или «требовать», вы на самом деле с помощью «Eval» под капотом - так, на самом деле, Eval является один из большинства используемых php-конструкций.

+0

Но, кажется, это плохая практика, если она используется в наших собственных кодах, не так ли? :) – Young

+6

Ну, я думаю, что 99% людей, говорящих о «плохих практиках», не могут объяснить причины. Они просто повторяют глупость, которую они слышали от других. – user187291

+0

Тем не менее, это не «необходимо», есть другие способы реализовать его, если хотите. И превратить «плохую практику» в круглый аргумент: если 99% людей не могут объяснить причины, это не безопасная ставка, что почти такое же количество людей не может решить, когда (и как) безопасно использовать eval() и не вмешиваться в него? – VolkerK

2

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

3

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

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

2

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

} 

 Смежные вопросы

  • Нет связанных вопросов^_^