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 截取字符串 分别适合GB2312和UTF8编码情况
Feb 12 PHP
php 错误处理经验分享
Oct 11 PHP
php+ajax做仿百度搜索下拉自动提示框(有实例)
Aug 21 PHP
php中用date函数获取当前时间有误的解决办法
Aug 02 PHP
PHP swfupload图片上传的实例代码
Sep 30 PHP
php编写批量生成不重复的卡号密码代码
May 14 PHP
基于php的CMS中展示文章类实例分析
Jun 18 PHP
WordPress中创建用户角色的相关PHP函数使用详解
Dec 25 PHP
PHP Cookei记录用户历史浏览信息的代码
Feb 03 PHP
[原创]php实现子字符串位置相互对调互换的方法
Jun 02 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
Sep 21 PHP
php实现断点续传大文件示例代码
Jun 19 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正则替换处理HTML页面的方法
2015/06/17 PHP
Yii实现Command任务处理的方法详解
2016/07/14 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
PHP token验证生成原理实例分析
2019/06/05 PHP
利用PHP计算有多少小于当前数字的数字方法示例
2020/08/26 PHP
JavaScript 创建对象和构造类实现代码
2009/07/30 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
JQuery选择器、过滤器大整理
2015/05/26 Javascript
jQuery实现时尚漂亮的弹出式对话框实例
2015/08/07 Javascript
javascript实现的猜数小游戏完整实例代码
2016/05/10 Javascript
iscroll碰到Select无法选择下拉刷新的解决办法
2016/05/21 Javascript
QRCode.js:基于JQuery的生成二维码JS库的使用
2017/06/23 jQuery
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
小程序实现图片预览裁剪插件
2019/11/22 Javascript
vue ajax 拦截原理与实现方法示例
2019/11/29 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
python 专题九 Mysql数据库编程基础知识
2017/03/16 Python
对Python中for复合语句的使用示例讲解
2018/11/01 Python
python绘制简单彩虹图
2018/11/19 Python
pycharm打开命令行或Terminal的方法
2019/01/16 Python
python编写俄罗斯方块
2020/03/13 Python
python requests包的request()函数中的参数-params和data的区别介绍
2020/05/05 Python
Lou & Grey美国官网:主打舒适性面料服饰
2017/12/21 全球购物
关于人生的感言
2014/01/17 职场文书
家长对小学生的评语
2014/01/28 职场文书
护校行动方案
2014/05/31 职场文书
政治学专业毕业生求职信
2014/08/11 职场文书
优秀党员学习焦裕禄精神思想汇报范文
2014/09/10 职场文书
合作协议书模板
2014/10/10 职场文书
2015年党员公开承诺书范文
2015/01/22 职场文书
委托公证书样本
2015/01/23 职场文书
2019年行政人事个人工作总结范本!
2019/07/19 职场文书
关于办理居住证的介绍信模板
2019/11/27 职场文书
MySQL 字符集 character
2022/05/04 MySQL