当前位置:首页 > CMS教程 > 其它CMS > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2022-01-23 14:03:18 浏览: 评论:0 

这篇文章主要介绍了laravel框架模型中非静态方法也能静态调用的原理,结合实例形式分析了laravel模型基类中使用魔术方法实现非静态方法进行静态调用的相关原理,需要的朋友可以参考下。

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

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

  1. <?php 
  2. namespace App\Models; 
  3. use Illuminate\Database\Eloquent\Model; 
  4. class User extends Model 
  5.   public static function getList() 
  6.   { 
  7.     return self::get()->toArray(); 
  8.   } 

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

  1. <?php 
  2. namespace App\Models; 
  3. use Illuminate\Database\Eloquent\Model; 
  4. class User extends Model 
  5.   protected function getList() 
  6.   { 
  7.     return $this->get()->toArray(); 
  8.   } 

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

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

  1. class Model 
  2.   public function __call($method$parameters
  3.   { 
  4.     if (in_array($method, ['increment''decrement'])) { 
  5.       return $this->$method(...$parameters); 
  6.     } 
  7.     return $this->forwardCallTo($this->newQuery(), $method$parameters); 
  8.   } 
  9.   public static function __callStatic($method$parameters
  10.   { 
  11.     return (new static)->$method(...$parameters); 
  12.   } 

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

  1. <?php 
  2. namespace App\Models; 
  3. class Model 
  4.   //在对象中调用一个不可访问方法时,__call()被调用 
  5.   public function __call($method$parameters
  6.   { 
  7.     echo '__call()'
  8.     return $this->{$method}(...$parameters); 
  9.   } 
  10.   //在静态上下文中调用一个不可访问方法时,__callStatic()被调用 
  11.   public static function __callStatic($method$parameters
  12.   { 
  13.     echo '__callStatic()'
  14.     //注意这里,通过延迟静态绑定,仍然new了一个实例 
  15.     return (new static)->{$method}(...$parameters); 
  16.   } 
  17.   private function test() 
  18.   { 
  19.     echo '被调用了<br>'
  20.   } 

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

  1. <?php 
  2. namespace App\Http\Controllers\Test; 
  3. use Illuminate\Http\Request; 
  4. use App\Http\Controllers\Controller; 
  5. use App\Models\Model; 
  6. class Test extends Controller 
  7.   public function index(Request $request
  8.   { 
  9.     //对象调用 
  10.     (new Model())->test(); 
  11.     //静态方法调用 
  12.     Model::test(); 
  13.   } 

结果显示调用成功。

Tags: laravel非静态方法

分享到: