Выполнение метода перехвата в PHP - PullRequest
4 голосов
/ 22 июня 2011

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

abstract class Base{    
    public function pre(){ print "Runing Base::pre()\n"; }
    public function pos(){ print "Runing Base::post()\n"; }
    abstract public function doIt();
}

class Cheating extends Base
{
    public function doIt(){
        $this->pre();
        print "Doing it the cheating way\n";
        $this->pos();
    }
}

Но на самом деле я хотел бы сделать следующее:

class Alpha extends Base
{
    public function doIt($x, $y){
        print "Doing it in Alpha with x=$x, y=$y";
    }
}

class Beta extends Base
{
    public function doIt($z){
        print "Doing it in Alpha with z=$z";
    }
}

И есть способ всегда запускать методы pre и pos без необходимости изменения самого метода doIt.

Очевидный способ, должен ли он быть однородным по всем производным от Base, будет примерно таким:

abstract class Base
{
    public function pre(){ print "Runing Base::pre()\n"; }
    public function pos(){ print "Runing Base::post()\n"; }

    public function process($a,$b){
        $this->pre();
        $this->doIt($a,$b);
        $this->pos();
    }

    abstract public function doIt();
}

class Wishful extends Base
{
    public function doIt($a, $b){
        print "Doing it the Wishful way with a=$a, b=$b\n";
    }
}

Проблема в том, что, поскольку у нас есть разные числа и типы параметров в каждой реализации doIt, это фактически не решает проблему.

Это звучит как случай "зацепок" - как их реализовать? Или любой другой достойный способ решения проблемы ... Я полагаю, что должен быть более простой способ, который я просто упускаю - вероятно, думая в кругах одну неправильную вещь.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 22 июня 2011

Вы должны взглянуть на аспектно-ориентированное программирование . Система литиевого каркаса *1003* использует такую ​​вещь. Zend Framework 2 также планирует использовать AOP.

Если вы хотите перехватить вызов функции на уровне двигателя, вы можете использовать intercept из PECL.

Google также показывает хороший фреймворк , из которого вы могли бы многое узнать. Посмотрите на его код.

Также, вот соответствующий вопрос SO: https://stackoverflow.com/questions/4738282/are-there-any-working-aspect-oriented-php-libraries

0 голосов
/ 22 июня 2011

Вызов с переменными аргументами можно выполнить с помощью: http://php.net/manual/en/function.call-user-func-array.php. Передать $ this как объект.

Извлечь аргументы немного сложнее, но можно сделать с помощью __call: http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods

0 голосов
/ 22 июня 2011

Звучит так, будто вы хотите что-то вроде:

function process()
{
  $this->pre();
  $result = call_user_func_array( array( $this, 'doIt' ), func_get_args() );
  $this->post();
  return $result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...