zoukankan      html  css  js  c++  java
  • laravel模型中非静态方法也能静态调用的原理

    刚开始用laravel模型时,为了方便一直写静态方法,进行数据库操作。

    <?php
    
    namespace AppModels;
    
    use IlluminateDatabaseEloquentModel;
    
    class User extends Model
    {
        public static function getList()
        {
            return self::get()->toArray();
        }
    }
    

    直到有朋友告诉可以不用这么写,声明一个 protected 方法,方法中用 $this。在外部使用时,也可以像调静态函数一样调用。

    <?php
    
    namespace AppModels;
    
    use IlluminateDatabaseEloquentModel;
    
    class User extends Model
    {
        protected function getList()
        {
            return $this->get()->toArray();
        }
    }
    

    试了一下,发现还真可以,按理说受保护的 protected 非静态方法,在外部是无法这么调用的 User::getList() 。

    但是在 laravel 中就可以,查看了下 Model 基类的代码,原来是因为实现了 __call() 和 __callStatic() 这两个魔术方法。

    class Model
    {
        public function __call($method, $parameters)
        {
            if (in_array($method, ['increment', 'decrement'])) {
                return $this->$method(...$parameters);
            }
    
            return $this->forwardCallTo($this->newQuery(), $method, $parameters);
        }
    
        public static function __callStatic($method, $parameters)
        {
            return (new static)->$method(...$parameters);
        }
    }
    

    我们试着自已实现下这两个魔术方法,看看效果。

    <?php
    
    namespace AppModels;
    
    class Model
    {
        //在对象中调用一个不可访问方法时,__call()被调用
        public function __call($method, $parameters)
        {
            echo '__call()';
            return $this->{$method}(...$parameters);
        }
    
        //在静态上下文中调用一个不可访问方法时,__callStatic()被调用
        public static function __callStatic($method, $parameters)
        {
            echo '__callStatic()';
            //注意这里,通过延迟静态绑定,仍然new了一个实例
            return (new static)->{$method}(...$parameters);
        }
    
        private function test()
        {
            echo '被调用了<br>';
        }
    }

    我们尝试调用 test() 方法。

    <?php
    
    namespace AppHttpControllersTest;
    
    use IlluminateHttpRequest;
    use AppHttpControllersController;
    use AppModelsModel;
    
    class Test extends Controller
    {
        public function index(Request $request)
        {
            //对象调用
            (new Model())->test();
    
            //静态方法调用
            Model::test();
        }
    }
    

    结果显示调用成功。

  • 相关阅读:
    204. Count Primes (Integer)
    203. Remove Linked List Elements (List)
    202. Happy Number (INT)
    201. Bitwise AND of Numbers Range (Bit)
    200. Number of Islands (Graph)
    199. Binary Tree Right Side View (Tree, Stack)
    198. House Robber(Array; DP)
    191. Number of 1 Bits (Int; Bit)
    190. Reverse Bits (Int; Bit)
    189. Rotate Array(Array)
  • 原文地址:https://www.cnblogs.com/jkko123/p/10805425.html
Copyright © 2011-2022 走看看