Был ли это первоначальный вопрос? Я искал динамический вызов метода и нашел этот вопрос. Это тот же синтаксис, что и andy.gurin, и я не вижу ссылки, которая показывает обновление вопроса. В любом случае ... Спасибо, что спросили, и спасибо соавторам :-)
Luc M
5
@Luc - Это был первоначальный вопрос. Оказалось, что у меня был правильный синтаксис, когда я спросил, но что-то еще было не так с моим кодом, поэтому он не сработал.
Все еще в силе спустя столько лет! Убедитесь, что вы обрезаете $ methodName, если это пользовательский контент. Я не мог заставить $ this -> $ methodName работать, пока не заметил, что у него есть начальный пробел.
Если это пользовательский контент, убедитесь, что вы делаете гораздо больше, чем просто обрезаете имя! Например ... проверка безопасности! ;)
Erk
Где-то в Интернете я подробно описал, как преобразовать введенный пользователем utf8 в символы, безопасные для Windows. QuickBooks рассказал мне об этом - и почему QB больше не является частью того, как я завершаю продажи ...
Крис К.
Вы действительно позволяете клиенту указывать ввод, который динамически вызывает некоторые методы ?! У меня нет слов
Mcsky
Очевидно, подтверждено и проверено, действительно ли класс содержит такой именованный метод. Есть много способов проверить значение. Это лучше, чем длинный оператор переключения.
Ответы:
Это можно сделать несколькими способами:
$this->{$methodName}($arg1, $arg2, $arg3); $this->$methodName($arg1, $arg2, $arg3); call_user_func_array(array($this, $methodName), array($arg1, $arg2, $arg3));
Вы даже можете использовать api отражения http://php.net/manual/en/class.reflection.php
источник
call_user_func_array
это то, что вам нужно.call_user_func_array($this->$name, ...)
и удивлялся, почему это не работает!Просто опустите фигурные скобки:
$this->$methodName($arg1, $arg2, $arg3);
источник
Вы можете использовать Перегрузку в PHP: Перегрузка
class Test { private $name; public function __call($name, $arguments) { echo 'Method Name:' . $name . ' Arguments:' . implode(',', $arguments); //do a get if (preg_match('/^get_(.+)/', $name, $matches)) { $var_name = $matches[1]; return $this->$var_name ? $this->$var_name : $arguments[0]; } //do a set if (preg_match('/^set_(.+)/', $name, $matches)) { $var_name = $matches[1]; $this->$var_name = $arguments[0]; } } } $obj = new Test(); $obj->set_name('Any String'); //Echo:Method Name: set_name Arguments:Any String echo $obj->get_name();//Echo:Method Name: get_name Arguments: //return: Any String
источник
Вы также можете использовать
call_user_func()
иcall_user_func_array()
источник
Если вы работаете в классе PHP, я бы рекомендовал использовать перегруженную функцию __call в PHP5. Вы можете найти ссылку здесь .
В основном __call делает для динамических функций то, что __set и __get делают для переменных в OO PHP5.
источник
Все еще в силе спустя столько лет! Убедитесь, что вы обрезаете $ methodName, если это пользовательский контент. Я не мог заставить $ this -> $ methodName работать, пока не заметил, что у него есть начальный пробел.
источник
В моем случае.
$response = $client->{$this->requestFunc}($this->requestMsg);
Использование PHP SOAP.
источник
Вы можете сохранить метод в одной переменной, используя закрытие:
class test{ function echo_this($text){ echo $text; } function get_method($method){ $object = $this; return function() use($object, $method){ $args = func_get_args(); return call_user_func_array(array($object, $method), $args); }; } } $test = new test(); $echo = $test->get_method('echo_this'); $echo('Hello'); //Output is "Hello"
РЕДАКТИРОВАТЬ: я отредактировал код, и теперь он совместим с PHP 5.3. Другой пример здесь
источник