Как я добавляю новый метод к объекту "на лету"?
$me= new stdClass;
$me->doSomething=function ()
{
echo 'I\'ve done something';
};
$me->doSomething();
//Fatal error: Call to undefined method stdClass::doSomething()
Вы можете использовать __ для этого позвоните
:
class Foo
{
public function __call($method, $args)
{
if (isset($this->$method)) {
$func = $this->$method;
return call_user_func_array($func, $args);
}
}
}
$foo = new Foo();
$foo->bar = function () { echo "Hello, this function is added at runtime"; };
$foo->bar();
Обновление: Показанный здесь подход имеет существенный недостаток: Функция new не является полноправным членом класса;
$this
не присутствует в методе при вызове таким образом. Это означает, что вам придется передавать объект в функцию в качестве параметра, если вы хотите работать с данными или функциями из экземпляра объекта! Кроме того, вы не сможете получить доступ кprivate
илиprotected
членам класса из этих функций.
Хороший вопрос и умная идея с использованием новых анонимных функций!
Интересно, что это работает:
$me->doSomething(); // Doesn't work
заменяя call_user_func на саму функцию:
call_user_func($me->doSomething); // Works!
что не работает, так это "правильный" способ:
call_user_func(array($me, "doSomething")); // Doesn't work
при таком вызове PHP требует, чтобы метод был объявлен в определении класса.
Это проблема видимости private
/ public
/ protected
?
Обновление: Нет. Невозможно вызвать функцию обычным способом даже из класса, так что это не проблема видимости. Передача фактической функции в call_user_func()
- единственный способ заставить ее работать.
На stackoverflow есть похожий пост, в котором разъясняется, что это достижимо только при реализации определенных паттернов проектирования.
Единственный другой способ - использование classkit, экспериментального расширения php. (также в посте)
Да, можно добавить метод к в класс PHP после того, как он определен. Вы хотите использовать classkit, который является "экспериментальным" расширением. Похоже. что это расширение не включено по по умолчанию, так что это зависит от того. вы можете скомпилировать пользовательский двоичный файл PHP или загружать PHP DLL, если вы работаете на windows (например. например, Dreamhost позволяет использовать PHP двоичные файлы, и их довольно легко установить).
Чтобы узнать, как это сделать с помощью eval, вы можете взглянуть на мою микро-структуру PHP, Halcyon, которая доступна на github . Он достаточно мал, чтобы вы могли без проблем разобраться в нем - сконцентрируйтесь на классе HalcyonClassMunger.