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


Posted in PHP onNovember 23, 2019

本文实例讲述了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框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP的历史和优缺点
Oct 09 PHP
PHP最常用的ini函数分析 针对PHP.ini配置文件
Apr 22 PHP
用PHP实现小写金额转换大写金额的代码(精确到分)
Jan 10 PHP
具有时效性的php加密解密函数代码
Jun 19 PHP
php过滤敏感词的示例
Mar 31 PHP
php源码分析之DZX1.5字符串截断函数cutstr用法
Jun 17 PHP
Yii中表单用法实例详解
Jan 05 PHP
php遍历替换目录下文件指定内容的方法
Nov 10 PHP
PHP实现图片批量打包下载功能
Mar 01 PHP
Laravel中encrypt和decrypt的实现方法
Sep 24 PHP
PHP生成加减算法方式的验证码实例
Mar 12 PHP
PHP面向对象程序设计之对象的遍历操作示例
Jun 12 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
Nov 23 #PHP
laravel框架创建授权策略实例分析
Nov 22 #PHP
laravel框架语言包拓展实现方法分析
Nov 22 #PHP
laravel框架邮箱认证实现方法详解
Nov 22 #PHP
laravel 框架结合关联查询 when()用法分析
Nov 22 #PHP
PHP实现微信提现功能(微信商城)
Nov 21 #PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
Nov 21 #PHP
You might like
php下删除一篇文章生成的多个静态页面
2010/08/08 PHP
php获取Google机器人访问足迹的方法
2015/04/15 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
php-msf源码详解
2017/12/25 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
Input 特殊事件onpopertychange和oninput
2009/06/17 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件
2011/12/21 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
jquery实现邮箱自动填充提示功能
2015/11/17 Javascript
探讨JavaScript标签位置的存放与功能有无关系
2016/01/15 Javascript
jQuery的实例及必知重要的jQuery选择器详解
2016/05/20 Javascript
javascript实现获取指定精度的上传文件的大小简单实例
2016/10/25 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
Angularjs实现分页和分页算法的示例代码
2016/12/23 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
微信小程序+云开发实现欢迎登录注册
2019/05/24 Javascript
微信小程序云函数添加数据到数据库的方法
2020/03/04 Javascript
小程序实现录音功能
2020/09/22 Javascript
[56:12]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第一场 6.3
2018/06/04 DOTA
基于python时间处理方法(详解)
2017/08/14 Python
在python中实现调用可执行文件.exe的3种方法
2019/07/07 Python
Python代理IP爬虫的新手使用教程
2019/09/05 Python
python Pillow图像处理方法汇总
2019/10/16 Python
Python3将ipa包中的文件按大小排序
2020/04/17 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
美国百货齐全的精品网站,提供美式风格的产品:Overstock.com
2016/07/22 全球购物
潘多拉意大利官方网上商城:网上选购PANDORA珠宝
2018/10/07 全球购物
Charles & Keith欧盟:新加坡时尚品牌
2019/08/01 全球购物
Ajax请求总共有多少种Callback
2016/07/17 面试题
11月升旗仪式讲话稿
2014/02/15 职场文书
2014银行授权委托书样本
2014/10/04 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
民事诉讼答辩状范文
2015/05/21 职场文书
《日月潭》教学反思
2016/02/20 职场文书