How to auto call function in php for every other function call

前端 未结 8 1961
夕颜
夕颜 2020-11-29 02:48
Class test{
    function test1()
    {
        echo \'inside test1\';
    }

    function test2()
    {
        echo \'test2\';
    }

    function test3()
    {
            


        
8条回答
  •  死守一世寂寞
    2020-11-29 03:13

    Maybe it is a little bit outdated but here come my 2 cents...

    I don't think that giving access to private methods via __call() is a good idea. If you have a method that you really don't want to be called outside of your object you have no way to avoid it happening.

    I think that one more elegant solution should be creating some kind of universal proxy/decorator and using __call() inside it. Let me show how:

    class Proxy
    {
        private $proxifiedClass;
    
        function __construct($proxifiedClass)
        {
            $this->proxifiedClass = $proxifiedClass;
        }
    
        public function __call($methodName, $arguments)
        {
    
            if (is_callable(
                    array($this->proxifiedClass, $methodName)))
            {
                doSomethingBeforeCall();
    
                call_user_func(array($this->proxifiedClass, $methodName), $arguments);
    
                doSomethingAfterCall();
            }
            else
            {
                $class = get_class($this->proxifiedClass);
                throw new \BadMethodCallException("No callable method $methodName at $class class");
            }
        }
    
        private function doSomethingBeforeCall()
        {
            echo 'Before call';
            //code here
        }
    
        private function doSomethingAfterCall()
        {
            echo 'After call';
            //code here
        }
    }
    

    Now a simply test class:

    class Test
    {
        public function methodOne()
        {
            echo 'Method one';
        }
    
        public function methodTwo()
        {
            echo 'Method two';
        }
    
        private function methodThree()
        {
            echo 'Method three';
        }
    
    }
    

    And all you need to do now is:

    $obj = new Proxy(new Test());
    
    $obj->methodOne();
    $obj->methodTwo();
    $obj->methodThree(); // This will fail, methodThree is private
    

    Advantages:

    1)You just need one proxy class and it will work with all your objects. 2)You won't disrespect accessibility rules. 3)You don't need to change the proxified objects.

    Disadvantage: You will lose the inferface/contract after wrapping the original object. If you use Type hinting with frequence maybe it is a problem.

提交回复
热议问题