views:

860

answers:

6

Hi,

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.

+1  A: 

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

marvin
haha snap! you beat me by 45s
adam
Please could you tell me why it's such a bad idea?
Tom
you 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.
marvin
Ah.... 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
+8  A: 

Use the call_user_func function:

http://php.net/manual/en/function.call-user-func.php

Example:

call_user_func('myClassName_'.$language.'::myFunctionName');
ILMV
Combined with `is_callable` and `method_exists` this would be my recommandation as well. To pass params look at `call_user_func_array` http://php.net/is_callable http://php.net/method_exists http://php.net/call_user_func_array
nikc
+1, I concur nikc :-)
ILMV
This sort of works and seems like the cleanest solution. Thanks
Tom
+1  A: 

I think you could do:

$classname = 'myClassName_' . $language;
$result = $classname::myFunctionName();

This is called Variable Functions

adam
It's too bad this only works in >=5.3.0 :(
Darryl Hein
+1  A: 

As far as i could understand your question, you need to get the class name which can be done using get_class function. On the other hand, the Reflection class can help you here which is great when it comes to methods, arguments, etc in OOP way.

Sarfraz
+1  A: 

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();
Silvio Donnini
A: 

@Silvio Donnini, @marvin, @adam:

Solutions like:

$yourClass::myFunctionName();

will not work. PHP will produce parse error.

Unfortunately, the only way is to use very slow call_user_func().

temuri
Only in <5.3.0 is this not allowed. Over 5.3.0 it is allowed.
Darryl Hein