eval () не возвращает результаты функции

У меня есть имя метода, которое хранится в столбце в БД, который выглядит так:

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 () опасен, есть ли другой способ прочитать строку как безопасный код?

Да, есть (на самом деле есть):

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

      демонстрация

  2. PHP имеет две функции: call_user_func и call_user_func_array для динамических вызовов функций / методов. Оба прекрасно документированы, поэтому я не буду подробно останавливаться на этом.
  3. Даже если все, что выше, недостаточно, PHP 5 поставляется с отличным API Reflection . К сожалению, в документации есть несколько примеров, но размышление – довольно большая тема для освещения здесь. В принципе, не стоит размышлять, прочитав, как это работает.