2010-12-13 2 views
2

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

Пример:

$a = new a(); 
$a->function1(); 

это сделало бы 2 вызовы функций: basicFunction(), а затем function1()

То же самое будет иметь место для любых последующих вызовов метода этого класса. возможно ли это в объектно-ориентированном PHP?

+0

Непонятно, хотите ли вы, чтобы функция 'basicFunction' вызывалась при вызове' function1' или когда вызывался ctor или когда вызывалась какая-либо функция. Кроме того, является 'basicFunction' частью класса' a'? Пожалуйста, уточните вопрос и, возможно, добавьте конкретный пример, иллюстрирующий, для чего вам это нужно. – Gordon

ответ

6

Простейшим бы просто вызвать метод

public function function1 { 
    $this->basicFunction(); 
    // … 
} 

То, что вы, вероятно, после того, как что-то вроде Aspect Oriented Programming. Однако это не распространено в PHP. Наиболее заметным является использование в Flow3 framework.

Для других более общих подходов может быть использован с PHP ООП, взгляните на

Это позволит вам добавить произвольное поведение и управление потоком во время выполнения.


(мета) Замечание, что мы действительно нужны четыре ответа, предполагающие использовать __call? Я предлагаю, чтобы различные ОП рассмотрели соответствующие ответы, разобрались в крошечных различиях и договорились о том, какой из них лучше. Остальные трое могли отозвать свои ответы.

2

В PHP нет ничего подобного. Вы можете, однако, смоделировать такое поведение с помощью magic method __call():

class YourClass { 
    public function __call($method, $args){ 
     // do what you want to do everywhere (i.e. call your basicFunction) 
     return call_user_func_array(array($this, 'base'.ucfirst($method)), $args); 
    } 

    private baseSomeFunction() { 
     // ... 
    } 
} 

Использования:

$obj = new YourClass(); 
$obj->someFunction(); // this calls baseSomeFunction and executes the code 
         // in the __call() method 

предваряя свою «волшебную» методу с чем-то вроде base гарантирует, что никто не может назвать свои личные функции и ограничивает этот доступ только для тех функций, которые были префиксом. Вы должны изменить этот префикс в соответствии с вашими потребностями.

3

Конечно, хотя это связано с некоторыми накладными расходами. Метод магии _call будет обрабатывать несуществующие методы, так что вы можете сделать:

class myClass { 
    public function __call($name, $arguments) { 

     $this->doSomething(); 
     $this->$name($arguments); 
    } 

    private function calledmethod() { ... } 

И тогда вы бы назвали:

$class->calledmethod(); 

Поскольку метод calledmethod не является публичной, _call бы получить вызывается тогда будет запускать ваш «базовый» метод, а затем calledmethod.

Я действительно обязан спросить, ПОЧЕМУ вам это нужно? Вероятно, это более элегантное решение, если бы вы описали фактическую проблему, которую пытаетесь решить.

+0

Я думаю '' 'в именах функций недействительными. – jwueller

+0

Это не вернет выход функции. – cypher

+1

@elusive: исправлено, слишком много js в последнее время, спасибо. @cypher: OP никогда ничего не говорил о возврате значения. – Erik

0

вы должны использовать __call magic method Для примера:

class Foo{ 
    public function __call($method_name, $arguments){ 
     $this->basicFunction(); 
     return call_user_func_array(array($this, $method_name), $arguments); 
    } 


    private function basicFunction(){} 
    protected function function1(){} 
} 
+1

Если функция1() является общедоступной, __call не будет использоваться. – StasM

+0

Да, спасибо, хорошая точка. – cypher

+0

Теперь я мог бы называть _every_ private method. – jwueller

0

Использование __call волшебной функции, как это:

class a { 
    private function function1() { ... } 
    public function __call($name, $args) { 
     /* do stuff */; 
     return call_user_func_array(array($this, $name), $args); 
    } 
} 

Примечание однако это не будет работать, если function1() вызывается из внутри класса. Затем вам нужно будет переименовать функцию1() и вызвать ее с другим именем. Идея заключается в том, что __call вызывается только в том случае, если функция не существует или ее не видно.

+0

Я мог бы назвать _every_ частную функцию этого класса. – jwueller

+0

@elusive - если вас это беспокоит, введите некоторые условия в __call. Это всего лишь предложение, а не производственный код :) – StasM

Смежные вопросы