- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
if (!class_exists($module, false))
{
// Get content from php file
$filepath = _PS_MODULE_DIR_.$module.'/'.$module.'.php';
$file = trim(file_get_contents(_PS_MODULE_DIR_.$module.'/'.$module.'.php'));
if (substr($file, 0, 5) == '<?php')
$file = substr($file, 5);
if (substr($file, -2) == '?>')
$file = substr($file, 0, -2);
// If (false) is a trick to not load the class with "eval".
// This way require_once will works correctly
if (eval('if (false){ '.$file.' }') !== false)
require_once( _PS_MODULE_DIR_.$module.'/'.$module.'.php' );
else
$errors[] = sprintf(Tools::displayError('%1$s (parse error in %2$s)'), $module, substr($filepath, strlen(_PS_ROOT_DIR_)));
}
Это оригинал кода из знаменитого Prestashop ...
Попросили написать модуль. Долго мучался, почему валидный код не работает. Потом нашел.
Смысл логики в строках 13-17 : мы не хотим принимать файлы модулей с eval функцией.
Поэтому мы сначала проверяем, есть ли eval в файле.
Как проверяем?
А давайте его просто выполним!
Если выполнится - тогда - require_once
В общем я О....ЕЛ! Других слов просто нет.
Мало того, так еще нужно следить, чтобы ваш файл модуля был валидным для eval функции.
Иначе - Parse error: syntax error ...
inkanus-gray 17.07.2013 16:45 # +4
“if (false)” используется, чтобы конструкция скомпилировалась, но не выполнилась: «... is a trick to not load...» А переводить а английского нужно с конца: «the class with "eval"» — исходная информация, а «to not load» — новая.
Да, мы пытаемся скомпилировать файл модуля, не выполняя его, а после попытки eval вернёт false, если не компилируется. Проверка выполняется оператором !==, чтобы отличить его от NULL, который eval вернёт в случае успешной компиляции.
В итоге require_once выполнится, только если включаемый файл валидный с точки зрения eval (для того и сравнение !== false). Наличие же eval во включаемом модуле не проверяется, поэтому смело можете закладывать в модуль бомбу.
corner578 19.07.2013 23:39 # +2
inkanus-gray 20.07.2013 01:56 # 0
Однако, я бы понял автора, если бы результат проверки кэшировался (записывался бы в конфиг), но грузить каждый раз модуль дважды — лишняя работа. Поэтому нет автору прощения, придётся признать Вашу правоту.
dekameron 22.07.2013 06:57 # 0
corner578 30.07.2013 22:48 # 0
chezz 31.08.2013 01:37 # 0