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 相关文章推荐
操作Oracle的php类
Oct 09 PHP
php IP转换整形(ip2long)的详解
Jun 06 PHP
PHP函数microtime()用法与说明
Dec 04 PHP
分享下php5类中三种数据类型的区别
Jan 26 PHP
PHP实现Javascript中的escape及unescape函数代码分享
Feb 10 PHP
PHP Cookie学习笔记
Aug 23 PHP
PHP中多线程的两个实现方法
Oct 14 PHP
替换php字符串中的单引号为双引号的方法
Feb 16 PHP
php魔法函数与魔法常量使用介绍
Jul 23 PHP
PHP实现根据数组某个键值大小进行排序的方法
Mar 13 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
Apr 21 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
May 28 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
收音机频率指针指示不准确和灵敏度低问题
2021/03/02 无线电
BBS(php &amp; mysql)完整版(六)
2006/10/09 PHP
php简单提示框alert封装函数
2010/08/08 PHP
PHP输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
php+html5基于websocket实现聊天室的方法
2015/07/17 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
2016/05/16 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
List Information About the Binary Files Used by an Application
2007/06/11 Javascript
JQuery为textarea添加maxlength属性的代码
2010/04/07 Javascript
基于jquery可配置循环左右滚动例子
2011/09/09 Javascript
一行代码实现纯数据json对象的深度克隆实现思路
2013/01/09 Javascript
Javascript 实现的数独解题算法网页实例
2013/10/15 Javascript
程序员必知35个jQuery 代码片段
2015/11/05 Javascript
AngularJS基础 ng-selected 指令简单示例
2016/08/03 Javascript
使用jquery.qrcode.js生成二维码插件
2016/10/17 Javascript
JS+html5 canvas实现的简单绘制折线图效果示例
2017/03/13 Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
2018/05/30 Javascript
浅析js实现网页截图的两种方式
2019/11/01 Javascript
JavaScript中的相等操作符使用详解
2019/12/21 Javascript
Python中的装饰器用法详解
2015/01/14 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
Python验证码截取识别代码实例
2020/05/16 Python
python线程池如何使用
2020/05/28 Python
python 制作简单的音乐播放器
2020/11/25 Python
python实现图片转字符画
2021/02/19 Python
英国领先的珍珠首饰品牌:Orchira
2016/09/11 全球购物
.net工程师笔试题
2012/06/09 面试题
人力资源管理专业毕业生自我评价
2013/09/21 职场文书
艺术专业大学生自我评价
2013/09/22 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
教师一帮一活动总结
2014/07/08 职场文书
会议开幕词
2015/01/28 职场文书
2015年煤矿工作总结
2015/04/28 职场文书
小学生组织委员竞选稿
2015/11/21 职场文书
2016教师廉洁从教心得体会
2016/01/13 职场文书