繁体   English   中英

PHP OOP类和函数

[英]PHP OOP classes and functions

我不确定如何命名,但是就此开始。 假设我有以下内容

class A {
    public function aa() {
       $this->bb();
    }
    public function bb() {

    }
}

class B extends a {

}

class C {
   __construct(B $service) {
       $this->service = $service;
   }
   public function aa() {

       $this->service->aa();
   }
}

我的代码调用将是

$C = new C(new B());
$C->aa();

因此,这基本上将执行我想要的A:aa() 如您所见,在A::aa()中将调用AA::bb()

我需要的。 调用AA :: bb()时,我想执行C类中定义的某些代码,但不允许更改A类。 我只能更改B类或C类。

我的想法是在B类中添加一个侦听器并像这样覆盖bb()函数

class B extends a {
    public $listener;
    bb() {
       parent::bb();
       $this->listener();
    }
}

class C {
   __construct(B $service) {
       $this->service = $service;
   }
   public function aa() {

       $this->service->listener = function() { }
       $this->service->aa();
   }
}

但是我不太喜欢这个主意,看起来也不是一个好主意。 我在这里有什么选择?

同样,我不能更改A类,而我只能调用C类。

PHP版本是5.3

您有两个选择。 延伸或装饰。

第一个有点像您已经编写的内容,但是,我不会对侦听器使用public可见性:

class Foo extends A {
    private $listener;
    public function setListener(callable $func) {
        $this->listener = $func;
    }
    public function bb() {
        call_user_func($this->listener);
        return parent:bb();
    }
}

在该示例中,我通过setter注入传递了侦听器,但是您也可以使用构造函数注入,并在重载的__construct()方法中传递$listened __construct() 扩展类时,“接口限制”不适用于构造函数的签名。


另一种方法是使用装饰器:

class Foo {
    private $target;
    public function __construct(A $target) {
        $this->target = $target;
    }

    public function bb($callback) {
        $callback();
        return $this->target->bb();
    }

    public function __call($method, $arguments) {
        return call_user_func_array( 
                array( $this->target, $method ),
                $arguments
            );
    }
}

第二种方法是让您更改界面。

您选择哪个选项取决于您实际需要实现的确切功能。 装饰器是一种解决方案,用于当您需要对对象行为进行彻底更改时-例如,对于添加访问控制而言,它真的很好。

我了解您要在A代码完成后在C执行代码。 您不能更改A。

如所写, C::aa调用A::aa ,后者调用A::bb并展开堆栈。 为什么在服务调用结束后不仅仅在C::aa工作?

class C {
   public function aa() {
       $this->service->aa();
       // whatever you want to do
   }
}

另一方面,如果您需要在调用A::aa之后但调用A::bb 之前调用代码,那么您发布的示例就足够清楚了:

class B extends a {
    public $listener;
    public function bb() {
       call_user_func($this->listener);
       parent::bb();
    }
}

注意使用call_user_func ,这是PHP 5.3调用存储在成员变量中的匿名函数所必需的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM