Dynamic static method call in PHP?
Solution 1
Use the call_user_func function:
http://php.net/manual/en/function.call-user-func.php
Example:
call_user_func('myClassName_' . $language . '::myFunctionName');
Solution 2
I think you could do:
$classname = 'myClassName_' . $language;
$result = $classname::myFunctionName();
This is called Variable Functions
Solution 3
I would encapsulate the creation of the class you need in a factory.
This way you will have a single entry point when you need to change your base name or the rules for mapping the language to the right class.
class YourClassFactory {
private $_language;
private $_basename = 'yourclass';
public YourClassFactory($language) {
$this->_language = $language;
}
public function getYourClass() {
return $this->_basename . '_' . $this->_language;
}
}
and then, when you have to use it:
$yourClass = $yourClassFactoryInstance->getYourClass();
$yourClass::myFunctionName();
Solution 4
As temuri said, parse error is produced, when trying '$className::functionName' :
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...
In my case (static method with 2 arguments), best solutions is to use call_user_func_array with 2 arrays (as suggested by nikc.org):
$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2));
BR
Solution 5
although i think the way you deal is a very bad idea, i think i may have a solution
$className = 'myClassName_'.$language;
$result = $className::myFunctionName();
i think this is what you want
Comments
-
Tom almost 2 years
Please could someone experienced in PHP help out with the following. Somewhere in my code, I have a call to a public static method inside a non-instantiated class:
$result = myClassName::myFunctionName();
However, I would like to have many such classes and determine the correct class name on the fly according to the user's language. In other words, I have:
$language = 'EN';
... and I need to do something like:
$result = myClassName_EN::myFunctionName();
I know I could pass the language as a parameter to the function and deal with it inside just one common class but for various reasons, I would prefer a different solution.
Does this make any sense, anyone? Thanks.
-
Tom over 14 yearsPlease could you tell me why it's such a bad idea?
-
nikc.org over 14 yearsCombined with
is_callable
andmethod_exists
this would be my recommandation as well. To pass params look atcall_user_func_array
php.net/is_callable php.net/method_exists php.net/call_user_func_array -
ahmetunal over 14 yearsyou can use language as a parameter, instead you choose to define a new class for it. Say you wanna support 200 different languages, will you sit and write 200 different classes. Also it will make your code extremely difficult to read and understand.
-
Tom over 14 yearsAh.... no there won't be 200 languages. It's a conscious downgrade of good practice to get something else done in a more practical way.
-
Tom over 14 yearsThis sort of works and seems like the cleanest solution. Thanks
-
penetra over 13 yearsOnly in <5.3.0 is this not allowed. Over 5.3.0 it is allowed.
-
tftd about 13 years
-
Nick Redmark almost 13 yearsjust a note: this works only since php 5.3 - better check if your host provider supports that version (the one I'm using doesn't).
-
btleffler about 10 years@nikc.org You can also pass parameters directly to
call_user_func()
if compiling them into an array is inconvenient. -
Olivier de Jonge over 9 yearsWon't work. Calls a user defined function or method given by the function parameter, with the following arguments. This function must be called within a method context, it can't be used outside a class... as mentioned in php.net/manual/en/function.forward-static-call.php
-
fred727 over 8 yearsFor me, this is the best solution. And according to my bench, this is the quickest too : 100.000 iterations took 0.28s with direct call, 0.32 with this solution, and 0.47 with call_user_func
-
Felipe Francisco over 8 yearsIs there a way to do this using ReflectionMethod class?
-
Josh Foskett over 7 yearsIt should be noted that you can also format it like this:
call_user_func(['myClassName_' . $language, 'myFunctionName']);
-
Uncoke about 5 yearsHere more info how the Factory Method Design Pattern works: sitepoint.com/understanding-the-factory-method-design-pattern
-
Amitesh Bharti over 2 yearssometimes we need a fully qualified class name then use this way to add the namespace in the class $className = '\\QuickBooksOnline\\API\Facades\\'.$resource; $postPayload = $className::create();