Я занимаюсь PHP в течение почти одного года, и я никогда не использовал функцию eval()
хотя я знаю ее использование. Но я нашел много вопросов об этом в SO.So может ли кто-нибудь показать мне простой пример, в котором необходимо использовать eval()
? И это хорошая или плохая практика?
Использование eval()
– это плохая практика, и если это необходимо для достижения чего-либо, это обычно является признаком базовой ошибки дизайна.
Я не могу думать о ситуации, когда необходимо использовать eval()
. (т. е. что-то не может быть достигнуто с использованием других языковых конструкций или путем исправления сломанного дизайна.) Заинтересованность в том, чтобы увидеть, возникают ли какие-либо настоящие случаи здесь, где на самом деле необходим eval, или альтернатива была бы ужасно сложной.
Единственный экземпляр, где это может потребоваться, – это выполнение кода, поступающего из внешнего источника (например, записей базы данных). Но это ошибка дизайна сама по себе IMO.
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-конструкций.
Плохой дизайн приложения всегда является таким примером.
Ну, я однажды использовал eval. Это было для системы, в которой пользователи могли вводить формулы, используя константы, выловленные из базовой системы.
Строка вроде:
(N * (G - 2,7)) / E
и константы, замененные значениями из системы eval, затем используются для получения значения. eval казался самым простым способом. Утверждение было отфильтровано только для операторов и прописных букв (нет двух рядом друг с другом), поэтому, возможно, это не «реальный» вариант использования eval, но он работает и довольно читабельен.
Тем не менее система в поиске огромна (200k + lines), и это единственное место, где используется eval.
Отличный пример командной строки php shell. Я думаю, вы могли бы разблокировать фактический код php и вместо этого писать свои расширения оболочки в C, но, похоже, гораздо более разумно это делать в php. Поскольку человек, предоставляющий код, должен иметь полный доступ к системе, нет никакой проблемы безопасности. Как только вы получите php, скомпилированный с помощью readline, такая вещь действительно действительно полезна.
Drupal (необязательно) использует eval, чтобы обеспечить готовность к расширению. Для этого требуется, чтобы пользователь (обычно администратор) вводил код для оценки и сохранял его в базе данных. У Drupal также есть много людей, уверяющих, что нет дыр в безопасности.
Использование eval довольно опасно, если смотреть со стороны безопасности. Во всяком случае, многие шаблонные двигатели используют eval, потому что они должны анализировать страницу и получать некоторые переменные или делать вычисления.
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); } } }
по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); } } }