Home  >  Q&A  >  body text

event - php中如何实现对一个已定义的类的方法调用的事件监听

class a{
    function mycall($var){
        return 'hello:'.$var;
    }
}

//invoke
$aobj = new a();
echo $aobj->mycall('abc');

想实现不修改现有调用流程代码的情况下,实现,对已定义类方法(这里是'mycall')的事件监听 比如拦截和修改mycall的返回

我知道可以通过包装类的类似的方法来解决问题,但如果不想修改现有调用流程,仅仅在这些类定义之前或之后添加代码来解决问题呢? 补充一下,系统环境还是5.3的,所以traits就暂时用不了了,有没有什么变通的办法?

天蓬老师天蓬老师2749 days ago531

reply all(5)I'll reply

  • 阿神

    阿神2017-04-10 14:31:22

    这样?

    trait T {
        private function mycall($var){
            return 'hello:'.str_pad($var, 4, '__', STR_PAD_LEFT);
        }
    }
    
    //invoke
    class  A{
        use T {
            mycall as traitmycall;
        }
    
        public function mycall($val)
        {
            return $this->traitmycall($val);
        }
    }
    
    $obj = new A();
    echo $obj->mycall('abc');
    

    reply
    0
  • 黄舟

    黄舟2017-04-10 14:31:22

    class a
    {
        function mycall($var)
        {
            $msg = 'hello:' . $var;
            $msg = $this->aftermycall($msg);
            return $msg;
        }
    
        function aftermycall($var)
        {
            $var .= 'aftermycall';
            return $var;
        }
    
    }
    $aobj = new a();
    echo $aobj->mycall('abc');
    

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:31:22

    使用 Traits需要注意优先级问题

    reply
    0
  • PHPz

    PHPz2017-04-10 14:31:22

    class a
    {
        function mycall($var)
        {
            $msg = 'hello:' . $var;
            $msg = $this->aftermycall($msg);
            return $msg;
        }
    
        function __call($method, $var)
        {
            echo __LINE__, PHP_EOL;
            // ....
        }
    
    }
    $aobj = new a();
    echo $aobj->mycall('abc');
    

    没有测试过

    reply
    0
  • PHPz

    PHPz2017-04-10 14:31:22

    魔术方法,很容易实现。只需要将要监听的类设置为private就行
    class a
    {
        private function mycall($var)
        {
            return 'hello:'.$var;
        }
    
        function __call($method, $var)
        {
            if($method=='要监听的方法'){
                //这里处理$var
                //调用$this->$method($var)
                //处理返回结果并返回
            }else{
                //其他不需要监听的private方法
            }
        }
    
    }
    $aobj = new a();
    echo $aobj->mycall('abc');
    

    reply
    0
  • Cancelreply