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企业级应用之常见缓存技术篇
Jan 27 PHP
php格式化日期实例分析
Nov 12 PHP
php检测数组长度函数sizeof与count用法
Nov 17 PHP
php面向对象中static静态属性和静态方法的调用
Feb 08 PHP
PHP中is_file()函数使用指南
May 08 PHP
php arsort 数组降序排序详细介绍
Nov 17 PHP
PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
Feb 07 PHP
微信公众号开发之通过接口删除菜单
Feb 20 PHP
PHP实现一维数组与二维数组去重功能示例
May 24 PHP
PHP异常类及异常处理操作实例详解
Dec 19 PHP
PHP配置文件php.ini中打开错误报告的设置方法
Jan 09 PHP
laravel添加角色和模糊搜索功能的实现代码
Jun 22 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
phpfans留言版用到的install.php
2007/01/04 PHP
php下用GD生成生成缩略图的两个选择和区别
2007/04/17 PHP
一些常用的php简单命令代码集锦
2007/09/24 PHP
php 禁止页面缓存输出
2009/01/07 PHP
php打开远程文件的方法和风险及解决方法
2013/11/12 PHP
ThinkPHP3.1新特性之对分组支持的改进与完善概述
2014/06/19 PHP
php实现图片上传并利用ImageMagick生成缩略图
2016/03/14 PHP
PDO::exec讲解
2019/01/28 PHP
犀利的js 函数集合
2009/06/11 Javascript
SyntaxHighlighter语法高亮插件使用说明
2011/08/14 Javascript
JQuery中的html()、text()、val()区别示例介绍
2014/09/01 Javascript
详谈JavaScript 匿名函数及闭包
2014/11/14 Javascript
理解jQuery stop()方法
2014/11/21 Javascript
2种jQuery 实现刮刮卡效果
2015/02/01 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
2015/10/10 Javascript
判断输入的字符串是否是日期格式的简单方法
2016/07/11 Javascript
从0开始学Vue
2016/10/27 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
jquery应用实例分享_实现手风琴特效
2018/02/01 jQuery
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
2018/08/19 Javascript
利用python实现简单的邮件发送客户端示例
2017/12/23 Python
python实现决策树分类(2)
2018/08/30 Python
Python3.6简单的操作Mysql数据库的三个实例
2018/10/17 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
Python一键安装全部依赖包的方法
2019/08/12 Python
Python使用Opencv实现图像特征检测与匹配的方法
2019/10/30 Python
pytorch 求网络模型参数实例
2019/12/30 Python
python批量合成bilibili的m4s缓存文件为MP4格式 ver2.5
2020/12/01 Python
html5 Canvas画图教程(5)—canvas里画曲线之arc方法
2013/01/09 HTML / CSS
浅谈HTML5 &amp; CSS3的新交互特性
2016/07/19 HTML / CSS
荷兰音乐会和音乐剧门票订购网站:Topticketshop
2019/08/27 全球购物
高中自我鉴定
2013/12/20 职场文书
感谢信范文大全
2015/01/23 职场文书
2015年招商引资工作总结
2015/04/25 职场文书
反邪教教育心得体会
2016/01/15 职场文书
晚会开幕词范文
2016/03/04 职场文书