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 相关文章推荐
Apache服务器无法使用的解决方法
May 08 PHP
PHP中使用BigMap实例
Mar 30 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
Jul 07 PHP
php微信浏览器分享设置以及回调详解
Aug 01 PHP
修改Laravel5.3中的路由文件与路径
Aug 10 PHP
PHP在线打包下载功能示例
Oct 15 PHP
PHP简单计算两个时间差的方法示例
Jun 20 PHP
浅谈laravel orm 中的一对多关系 hasMany
Oct 21 PHP
thinkphp5.1框架模板赋值与变量输出示例
May 25 PHP
Cookie跨域问题解决方案代码示例
Nov 24 PHP
PHP实现简单注册登录系统
Dec 28 PHP
ThinkPHP5.1的权限控制怎么写?分享一个AUTH权限控制
Mar 09 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
thinkphp视图模型查询提示ERR: 1146:Table 'db.pr_order_view' doesn't exist的解决方法
2014/10/30 PHP
php中explode函数用法分析
2014/11/15 PHP
FormValid0.5版本发布,带ajax自定义验证例子
2007/08/17 Javascript
javascript奇异的arguments分析
2010/10/20 Javascript
jquery1.5.1中根据元素ID获取元素对象的代码
2011/04/02 Javascript
往光标所在位置插入值的js代码
2013/09/22 Javascript
浅析JavaScript中的typeof运算符
2013/11/30 Javascript
javascript计算当月剩余天数(天数计算器)示例代码
2014/01/09 Javascript
JS实现样式清新的横排下拉菜单效果
2015/10/09 Javascript
基于jQuery实现仿搜狐辩论投票动画代码(附源码下载)
2016/02/18 Javascript
javascript url几种编码方式详解
2016/06/06 Javascript
javascript正则表达式之分组概念与用法实例
2016/06/16 Javascript
js简单判断flash是否加载完成的方法
2016/06/21 Javascript
jquery之基本选择器practice(实例讲解)
2017/09/30 jQuery
javascript系统时间设置操作示例
2019/06/17 Javascript
js实现淘宝浏览商品放大镜功能
2020/10/28 Javascript
通过滑动翻页效果实现和移动端click事件问题
2021/01/26 Javascript
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
[54:29]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第二场
2018/04/09 DOTA
Python学习笔记(一)(基础入门之环境搭建)
2014/06/05 Python
Python编程之列表操作实例详解【创建、使用、更新、删除】
2017/07/22 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python爬虫:url中带字典列表参数的编码转换方法
2019/08/21 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
解决Jupyter Notebook使用parser.parse_args出现错误问题
2020/04/20 Python
C语言面试题
2013/05/19 面试题
高中军训感想300字
2014/03/04 职场文书
捐献物资倡议书范文
2014/05/19 职场文书
标准版离职证明书
2014/09/12 职场文书
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
2014年销售部工作总结
2014/12/01 职场文书
2014年纠风工作总结
2014/12/08 职场文书
文明倡议书
2015/01/19 职场文书
工程竣工验收申请报告
2015/05/15 职场文书
MySQL系列之八 MySQL服务器变量
2021/07/02 MySQL
python高温预警数据获取实例
2022/07/23 Python