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 如何向 MySQL 发送数据
Oct 09 PHP
CodeIgniter基本配置详细介绍
Nov 12 PHP
Codeigniter出现错误提示Error with CACHE directory的解决方案
Jun 12 PHP
php建立Ftp连接的方法
Mar 07 PHP
php自动给网址加上链接的方法
Jun 02 PHP
php获取图片信息的方法详解
Dec 10 PHP
php实现替换手机号中间数字为*号及隐藏IP最后几位的方法
Nov 16 PHP
Laravel多用户认证系统示例详解
Mar 13 PHP
PHP strripos函数用法总结
Feb 11 PHP
PHP快速排序算法实现的原理及代码详解
Apr 03 PHP
laravel 判断查询数据库返回值的例子
Oct 11 PHP
eval(cmd)与eval($cmd)的区别与联系
Jul 07 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读取CURL模拟登录时生成Cookie文件的方法
2014/11/04 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
贴一个在Mozilla中常用的Javascript代码
2007/01/09 Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
2015/01/26 Javascript
javascript每日必学之多态
2016/02/23 Javascript
简单理解js的冒泡排序
2016/12/19 Javascript
运用jQuery写的验证表单(实例讲解)
2017/07/06 jQuery
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
vue 指定组件缓存实例详解
2018/04/01 Javascript
vue.js 中使用(...)运算符报错的解决方法
2018/08/09 Javascript
Vue表单及表单绑定方法
2018/09/04 Javascript
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
详解Vue前端生产环境发布配置实战篇
2019/05/07 Javascript
Vue中父子组件的值传递与方法传递
2020/09/28 Javascript
使用IPython下的Net-SNMP来管理类UNIX系统的教程
2015/04/15 Python
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
Python2.7 实现引入自己写的类方法
2018/04/29 Python
PyQt5显示GIF图片的方法
2019/06/17 Python
python f-string式格式化听语音流程讲解
2019/06/18 Python
pytorch 数据处理:定义自己的数据集合实例
2019/12/31 Python
Python简单实现区域生长方式
2020/01/16 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
加拿大领先的牛仔零售商:Bluenotes
2018/01/22 全球购物
管理科学大学生求职信
2013/11/13 职场文书
办护照工作证明范本
2014/01/14 职场文书
学生干部的自我评价分享
2014/01/18 职场文书
电气自动化求职信
2014/06/24 职场文书
专题民主生活会对照检查材料思想汇报
2014/09/29 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
趣味运动会开幕词
2015/01/28 职场文书
小学运动会加油词
2015/07/18 职场文书
工作自我评价范文
2019/03/21 职场文书
创业计划书之物流运送
2019/09/17 职场文书
关于springboot 配置date字段返回时间戳的问题
2021/07/25 Java/Android
拙作再改《我的收音机情缘》
2022/04/05 无线电