Динамический статический вызов метода в PHP? - PullRequest
57 голосов
/ 21 января 2010

Пожалуйста, кто-нибудь, имеющий опыт в PHP, может помочь со следующим. Где-то в моем коде у меня есть вызов общедоступного статического метода внутри неинстанцированного класса:

$result = myClassName::myFunctionName();

Однако я хотел бы иметь много таких классов и определять правильное имя класса на лету в соответствии с языком пользователя. Другими словами, у меня есть:

$language = 'EN';

... и мне нужно сделать что-то вроде:

$result = myClassName_EN::myFunctionName();

Я знаю, что мог бы передать язык в качестве параметра функции и работать с ним только в одном общем классе, но по разным причинам я бы предпочел другое решение.

Имеет ли это какой-нибудь смысл? Спасибо.

Ответы [ 9 ]

106 голосов
/ 21 января 2010

Используйте функцию call_user_func :

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

Пример:

call_user_func('myClassName_' . $language . '::myFunctionName');
18 голосов
/ 21 января 2010

Я думаю вы могли бы сделать:

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

Это называется Переменные функции

15 голосов
/ 21 января 2010

Я бы инкапсулировал создание класса, который вам нужен на фабрике.

Таким образом, у вас будет единственная точка входа, когда вам нужно изменить базовое имя или правила для сопоставления языка с правильным классом.

    class YourClassFactory {

        private $_language;
        private $_basename = 'yourclass';

        public YourClassFactory($language) {
            $this->_language = $language;
        }

        public function getYourClass() {
            return $this->_basename . '_' . $this->_language;
        }    
    } 

и затем, когда вы должны использовать его:

$yourClass = $yourClassFactoryInstance->getYourClass();
$yourClass::myFunctionName();
6 голосов
/ 15 ноября 2012

Как сказал Темури, при разборе '$ className :: functionName' выдается ошибка разбора:

Ошибка разбора: синтаксическая ошибка, неожиданный T_PAAMAYIM_NEKUDOTAYIM ...

В моем случае (статический метод с 2 аргументами) лучшим решением будет использование call_user_func_array с 2 массивами (как предложено nikc.org):

$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2));

BR

6 голосов
/ 21 января 2010

хотя я думаю, что ваше поведение - очень плохая идея, я думаю, что у меня может быть решение

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

Я думаю, это то, что вы хотите

1 голос
/ 23 марта 2016

Вы можете легко сделать следующее:

<?php

class B {

    public static $t = 5;

    public static function t($h) {
        return "Works!" . $h;
    }
}

$g = 't';
$class = 'B';

echo $class::$g('yes'); //Works! Yes

И все будет работать нормально, проверено на PHP 5.2> =

1 голос
/ 21 января 2010

Насколько я понимаю ваш вопрос, вам нужно получить имя класса, которое можно сделать с помощью функции get_class . С другой стороны, класс Reflection может помочь вам в этом, что здорово, когда речь идет о методах, аргументах и ​​т. Д. ООП.

0 голосов
/ 13 сентября 2014

Я знаю, что это старый поток, но начиная с PHP 5.3.0 вы должны использовать forward_static_call

$result = forward_static_call(array('myClassName_EN', 'myFunctionName'));

Используя переменную $ language, она может выглядеть так:

$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName'));
0 голосов
/ 09 июля 2010

Решения, такие как:

$yourClass::myFunctionName();

не будет работать. PHP выдаст ошибку разбора.

К сожалению, единственный способ - использовать очень медленно call_user_func().

...