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采集时被封ip的解决方法
Aug 29 PHP
解析PHP中的正则表达式以及模式匹配
Jun 19 PHP
CodeIgniter基本配置详细介绍
Nov 12 PHP
php之Smarty模板使用方法示例详解
Jul 08 PHP
Laravel 5 框架入门(二)构建 Pages 的管理功能
Apr 09 PHP
PHP SPL标准库中的常用函数介绍
May 11 PHP
PHP生成和获取XML格式数据的方法
Mar 04 PHP
在CentOS系统上从零开始搭建WordPress博客的全流程记录
Apr 21 PHP
Yii2基于Ajax自动获取表单数据的方法
Aug 10 PHP
thinkPHP js文件中U方法不被解析问题的解决方法
Dec 05 PHP
PHP+jQuery实现双击修改table表格功能示例
Feb 21 PHP
laravel异步监控定时调度器实例详解
Jun 21 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上传、管理照片示例
2006/10/09 PHP
php adodb分页实现代码
2009/03/19 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
php给一组指定关键词添加span标签的方法
2015/03/31 PHP
php 判断页面或图片是否经过gzip压缩的方法
2017/04/05 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
Extjs学习笔记之六 面版
2010/01/08 Javascript
JS弹出对话框返回值代码(asp.net后台)
2010/12/28 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
百度地图自定义控件分享
2015/03/04 Javascript
jQuery表单验证简单示例
2016/10/17 Javascript
js简单正则验证汉字英文及下划线的方法
2016/11/28 Javascript
JS中如何实现点击a标签返回页面顶部的问题
2017/01/19 Javascript
vue+Java后端进行调试时解决跨域问题的方式
2017/10/19 Javascript
JavaScript重复元素处理方法分析【统计个数、计算、去重复等】
2017/12/14 Javascript
Angular2整合其他插件的方法
2018/01/20 Javascript
JavaScript满天星导航栏实现方法
2018/03/08 Javascript
实例讲解v-if和v-show的区别
2019/01/31 Javascript
IE11下处理Promise及Vue的单项数据流问题
2019/07/24 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
element 中 el-menu 组件的无限极循环思路代码详解
2020/04/26 Javascript
Nuxt.js 静态资源和打包的操作
2020/11/06 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
深入理解Javascript中的this关键字
2015/03/27 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
2019/02/28 Python
10个Python面试常问的问题(小结)
2019/11/20 Python
python with语句的原理与用法详解
2020/03/30 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
美国购买体育、音乐会和剧院门票网站:SelectATicket
2019/09/08 全球购物
创业计划书的内容步骤和要领
2014/01/04 职场文书
2014年教师节演讲稿
2014/09/03 职场文书
2014年学生资助工作总结
2014/12/18 职场文书
生日赠语
2015/06/23 职场文书
诚实守信主题班会
2015/08/13 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书