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