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 相关文章推荐
通过ICQ网关发送手机短信的PHP源程序
Oct 09 PHP
PHP脚本的10个技巧(7)
Oct 09 PHP
PHP 数组入门教程小结
May 20 PHP
服务器web工具 php环境下
Dec 29 PHP
php购物车实现代码
Oct 10 PHP
php输入流php://input使用示例(php发送图片流到服务器)
Dec 25 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
Aug 21 PHP
PHP魔术方法__GET、__SET使用实例
Nov 25 PHP
php按字符无乱码截取中文的方法
Mar 27 PHP
laravel5.2表单验证,并显示错误信息的实例
Sep 29 PHP
PHP利用curl发送HTTP请求的实例代码
Jul 09 PHP
PHP读取文件或采集时解决中文乱码
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
DOTA2 玩家自创拉野攻略 特色英雄快速成长篇
2020/04/20 DOTA
Ext.data.PagingMemoryProxy分页一次性读取数据的实现代码
2010/04/07 PHP
PHP常见错误提示含义解释(实用!值得收藏)
2016/04/25 PHP
php项目开发中用到的快速排序算法分析
2016/06/25 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
分享一个自己写的table表格排序js插件(高效简洁)
2011/10/29 Javascript
javascript获取dom的下一个节点方法
2014/09/05 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
2014/09/25 Javascript
jquery转盘抽奖功能实现
2015/11/13 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
纯js和css完成贪吃蛇小游戏demo
2016/09/01 Javascript
移动端底部导航固定配合vue-router实现组件切换功能
2019/06/13 Javascript
浅谈vue中组件绑定事件时是否加.native
2019/11/09 Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
2020/08/18 Javascript
[04:09]2018年度DOTA2社区贡献奖-完美盛典
2018/12/16 DOTA
下载安装setuptool和pip linux安装pip    
2014/01/24 Python
Python实现把json格式转换成文本或sql文件
2015/07/10 Python
python3实现读取chrome浏览器cookie
2016/06/19 Python
Python 中的lambda函数介绍
2018/10/10 Python
python判断自身是否正在运行的方法
2019/08/08 Python
python将数组n等分的实例
2019/12/02 Python
python 实现让字典的value 成为列表
2019/12/16 Python
将matplotlib绘图嵌入pyqt的方法示例
2020/01/08 Python
Win10里python3创建虚拟环境的步骤
2020/01/31 Python
开启Django博客的RSS功能的实现方法
2020/02/17 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
Django windows使用Apache实现部署流程解析
2020/10/12 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
Charlotte Tilbury美国官网:英国美妆品牌
2017/10/13 全球购物
中学老师的自我评价
2013/11/07 职场文书
经典而简洁的婚礼主持词
2014/03/13 职场文书
2015年复活节活动总结
2015/02/27 职场文书
2016大学生入党积极分子心得体会
2016/01/06 职场文书
医院中层管理人员培训心得体会
2016/01/11 职场文书
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL