I use eval()
in my current project like this:
if (class_exists($class_name)) //$class_name depends on user input
eval($class_name.'::MyStaticMethod()');
eval()
is executed if and only if class with the name $class_name
exists so it's kinda safe, but I still don't think that this is the best solution.
Can I do the same what code above does without eval()
?
I have recently answered this question. The last part of my answer perfectly answers this question and is much more useful for future readers than answers provided here. That's why I am answering my own question.
PHP has features that gives possibility to avoid using eval
in most cases:
PHP is very dynamic language. It has ability to do following stuff with strings
:
Define and/or get variable (supported from PHP 4.3). For example:
$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'});
Demo
Call function (supported from PHP 4.3). For example:
// 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.'));
Demo
Create instance of class (supported from PHP 5.0). For example:
class MyClass {
public function __construct() {
echo 'Constructing MyClass'."\n";
}
}
$className = 'MyClass';
$objFromString = new $className();
// Outputs: object(MyClass)#1 (0) {}
var_dump($objFromString);
Demo
Call static method (supported from PHP 5.0). For example:
class MyClass {
public static function staticMethod() {
return 'MyClass::staticMethod called';
}
}
$staticMethodName = 'staticMethod';
// Outputs: string(28) "MyClass::staticMethod called"
var_dump(MyClass::$staticMethodName());
Demo
And from PHP 5.3 class name can also be defined by string. Example:
class MyClass {
public static function staticMethod() {
return 'MyClass::staticMethod called';
}
}
$className = 'MyClass';
$staticMethodName = 'staticMethod';
var_dump($className::$staticMethodName());
var_dump($className::staticMethod());
Demo
Call instance method of object (supported from PHP 5.0). For example:
class MyClass {
public function instanceMethod() {
return 'MyClass::instanceMethod called';
}
}
$methodName = 'instanceMethod';
$obj = new MyClass();
// Outputs: string(30) "MyClass::instanceMethod called"
var_dump($obj->$methodName());
Demo
Access static and instance properties of object (supported from PHP 5.0). For example:
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});
Demo
call_user_func
and call_user_func_array
for dynamic function/method calls. Both are perfectly documented so I won't go in details here.Reflection
API. Unfortunately, documentation has few examples but reflection is quite large topic to cover here. Basically, It's not a big deal to use reflection after reading how it works.I'd suggest call_user_func
.
An alternative to call_user_func()
would be calling it like this:
$class_and_method = 'Class::MyStaticMethod()';
$class_and_method();
yes:
call_user_func(array($class_name, 'MyStaticMethod'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With