У меня есть имя метода, которое хранится в столбце в БД, который выглядит так:
customs::nicknames($data)
Это связанный класс:
class customs extends service { function __construct() { parent::__construct(); } public static function nicknames($data) { return $data; } }
Когда я называю это так:
$merge = eval($error['custom'] . ';');
Содержимое переменной $ data не возвращается. Просто, чтобы дать ему попробовать, я попытался с echo
и он корректно возвращает массив в строку преобразования php error. Таким образом, переменная $data
считывается правильно. Но почему он ничего не возвращает?
Если я попытаюсь вызвать этот метод, не используя eval()
как это:
$merge = customs::nicknames($data);
Правильно возвращаются $data
.
Так что случилось?
Почему eval()
не может вернуть результаты метода? Как я могу решить эту проблему?
Почему eval () не может вернуть результаты метода?
Просто потому, что вы ничего не возвращаете в своей части.
Docs:
eval () возвращает
NULL
если в вычисленном коде не вызван возврат , и в этом случае возвращается значение, переданное в return .
Как я могу решить эту проблему?
Вы можете назначить переменную ( $merge
в данном примере) в eval
. Например:
eval('$merge =' . $error['custom'] . ';');
или return
значение в eval
. Например:
$merge = eval('return '.$error['custom'].';');
Примечание. Не используйте eval
в реальных приложениях.
Предупреждение из документов:
Конструкция языка eval () очень опасна, поскольку позволяет выполнять произвольный PHP-код. Поэтому его использование не рекомендуется. Если вы тщательно проверили, что нет другого выбора, кроме использования этой конструкции, обратите особое внимание на то, чтобы не передавать какие-либо данные, предоставленные пользователем, без предварительной проверки.
Если eval () опасен, есть ли другой способ прочитать строку как безопасный код?
Да, есть (на самом деле есть):
PHP – очень динамичный язык. Он имеет возможность делать следующие вещи со strings
:
Определить и / или получить переменную (поддерживается PHP 4.3). Например:
$variableName = 'MyVariable'; // Create new variable with the name defined in variable $variableName ${$variableName} = 'MyValue'; //Outputs: string(7) "MyValue" var_dump($MyVariable); //Outputs: string(7) "MyValue" var_dump(${'MyVariable'});
демонстрация
Функция вызова (поддерживается с PHP 4.3). Например:
// Create function with the name defined in variable $functionName function MyFunction($argument) { return 'Argument passed is: '.$argument; } $functionName = 'MyFunction'; // Outputs: // string(48) "Argument passed is: Calling MyFunction directly." var_dump(MyFunction('Calling MyFunction directly.')); // Outputs: // string(51) "Argument passed is: Calling MyFunction with string." var_dump($functionName('Calling MyFunction with string.'));
демонстрация
Создать экземпляр класса (поддерживается с PHP 5.0). Например:
class MyClass { public function __construct() { echo 'Constructing MyClass'."\n"; } } $className = 'MyClass'; $objFromString = new $className(); // Outputs: object(MyClass)#1 (0) {} var_dump($objFromString);
демонстрация
Вызов статического метода (поддерживается PHP 5.0). Например:
class MyClass { public static function staticMethod() { return 'MyClass::staticMethod called'; } } $staticMethodName = 'staticMethod'; // Outputs: string(28) "MyClass::staticMethod called" var_dump(MyClass::$staticMethodName());
демонстрация
А из PHP 5.3 имя класса также может быть определено строкой. Пример:
class MyClass { public static function staticMethod() { return 'MyClass::staticMethod called'; } } $className = 'MyClass'; $staticMethodName = 'staticMethod'; var_dump($className::$staticMethodName()); var_dump($className::staticMethod());
демонстрация
Вызов метода экземпляра объекта (поддерживается PHP 5.0). Например:
class MyClass { public function instanceMethod() { return 'MyClass::instanceMethod called'; } } $methodName = 'instanceMethod'; $obj = new MyClass(); // Outputs: string(30) "MyClass::instanceMethod called" var_dump($obj->$methodName());
демонстрация
Доступ к статическим свойствам экземпляра объекта (поддерживается PHP 5.0). Например:
class MyClass { public static $myStaticProperty; public $myInstanceProperty; } $staticPropertyName = 'myStaticProperty'; $instancePropertyName = 'myInstanceProperty'; MyClass::${$staticPropertyName} = 'my static value'; $obj = new MyClass(); $obj->{$instancePropertyName} = 'my instance value'; var_dump(MyClass::${$staticPropertyName}); var_dump($obj->{$instancePropertyName});
демонстрация
call_user_func
и call_user_func_array
для динамических вызовов функций / методов. Оба прекрасно документированы, поэтому я не буду подробно останавливаться на этом. Reflection
. К сожалению, в документации есть несколько примеров, но размышление – довольно большая тема для освещения здесь. В принципе, не стоит размышлять, прочитав, как это работает.