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 相关文章推荐
Linux下将excel数据导入到mssql数据库中的方法
Feb 08 PHP
PHP中获取内网用户MAC地址(WINDOWS/linux)的实现代码
Aug 11 PHP
php魔术方法与魔术变量、内置方法与内置变量的深入分析
Jun 03 PHP
php的数组与字符串的转换函数整理汇总
Jul 18 PHP
php与flash as3 socket通信传送文件实现代码
Aug 16 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
Feb 14 PHP
Symfony模板的快捷变量用法实例
Mar 17 PHP
SSO单点登录的PHP实现方法(Laravel框架)
Mar 23 PHP
PHP文件操作详解
Dec 30 PHP
Laravel实现autoload方法详解
May 07 PHP
laravel实现批量更新多条记录的方法示例
Oct 22 PHP
PHP 中魔术常量的实例详解
Oct 26 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 ajax 静态分页过程形式
2011/09/02 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
PHP大文件分割分片上传实现代码
2020/12/09 PHP
jquery快捷动态绑定键盘事件的操作函数代码
2013/10/17 Javascript
jquery 日期控件datepicker属性详细解析
2013/11/08 Javascript
原生js实现百叶窗效果及原理介绍
2016/04/12 Javascript
浅析$.getJSON异步请求和同步请求
2016/06/06 Javascript
详解Vue快速零配置的打包工具——parcel
2018/01/16 Javascript
详解Vue 多级组件透传新方法provide/inject
2018/05/09 Javascript
vue里的data要用return返回的原因浅析
2019/05/28 Javascript
vue父子组件的通信方法(实例详解)
2019/11/10 Javascript
JS实现水平移动与垂直移动动画
2019/12/19 Javascript
js实现简单选项卡制作
2020/08/05 Javascript
浅析JavaScript中的事件委托机制跟深浅拷贝
2021/01/20 Javascript
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
Python tkinter模块弹出窗口及传值回到主窗口操作详解
2017/07/28 Python
Python之文字转图片方法
2018/05/10 Python
Python读取Excel表格,并同时画折线图和柱状图的方法
2018/10/14 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
Python 在函数上添加包装器
2020/07/28 Python
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
拉夫劳伦爱尔兰官方网站:Ralph Lauren爱尔兰
2020/04/10 全球购物
年度考核评语
2014/01/19 职场文书
幼教简历自我评价
2014/01/28 职场文书
幼儿园优秀教师事迹
2014/02/13 职场文书
基层领导干部“四风”问题批评与自我批评
2014/09/23 职场文书
2014年工程师工作总结
2014/11/25 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
毕业论文致谢词
2015/05/14 职场文书
2015年语文教研组工作总结
2015/05/23 职场文书
毕业论文答辩演讲稿
2015/06/23 职场文书
Python利器openpyxl之操作excel表格
2021/04/17 Python
微信小程序实现录音Record功能
2021/05/09 Javascript
在js中修改html body的样式
2021/11/11 Javascript