当前位置 主页 > 服务器问题 > Linux/apache问题 >

    laravel框架模型中非静态方法也能静态调用的原理分析

    栏目:Linux/apache问题 时间:2019-11-24 13:29

    本文实例讲述了laravel框架模型中非静态方法也能静态调用的原理.分享给大家供大家参考,具体如下:

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

    <?php
    namespace App\Models;
    use Illuminate\Database\Eloquent\Model;
    class User extends Model
    {
      public static function getList()
      {
        return self::get()->toArray();
      }
    }
    
    

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

    <?php
    namespace App\Models;
    use Illuminate\Database\Eloquent\Model;
    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 App\Models;
    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 App\Http\Controllers\Test;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use App\Models\Model;
    class Test extends Controller
    {
      public function index(Request $request)
      {
        //对象调用
        (new Model())->test();
        //静态方法调用
        Model::test();
      }
    }
    
    

    结果显示调用成功。

    更多关于Laravel相关内容感兴趣的读者可查看本站专题:《Laravel框架入门与进阶教程》、《php优秀开发框架总结》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

    希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。