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脚本的10个技巧(7)
Oct 09 PHP
php 中的str_replace 函数总结
Apr 27 PHP
创建配置文件 用PHP写出自己的BLOG系统 2
Apr 12 PHP
PHP自动选择 连接本地还是远程数据库
Dec 02 PHP
php出现内存位置访问无效错误问题解决方法
Aug 16 PHP
如何使用PHP对网站验证码进行破解
Sep 17 PHP
php计算年龄精准到年月日
Nov 17 PHP
php简单实现数组分页的方法
Apr 30 PHP
浅谈Laravel中的一个后期静态绑定
Aug 11 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
Aug 17 PHP
Laravel 5使用Laravel Excel实现Excel/CSV文件导入导出的功能详解
Oct 11 PHP
Laravel5.4框架使用socialite实现github登录的方法
Mar 20 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按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
Firefox outerHTML实现代码
2009/06/04 Javascript
JQuery Tips(2) 关于$()包装集你不知道的
2009/12/14 Javascript
Javascript 颜色渐变效果的实现代码
2013/10/01 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
2014/01/13 Javascript
删除条目时弹出的确认对话框
2014/06/05 Javascript
js实现右下角提示框的方法
2015/02/03 Javascript
JavaScript函数作用域链分析
2015/02/13 Javascript
Knockout自定义绑定创建方法
2015/12/26 Javascript
基于javascript实现图片懒加载
2016/01/05 Javascript
Bootstrap创建可折叠的组件
2016/02/23 Javascript
jquery自适应布局的简单实例
2016/05/28 Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
2016/11/23 Javascript
js实现符合国情的日期插件详解
2017/01/19 Javascript
AngularJS 防止页面闪烁的方法
2017/03/09 Javascript
原生javascript上传图片带进度条【实例分享】
2017/04/06 Javascript
bootstrap table单元格新增行并编辑
2017/05/19 Javascript
vue-router 权限控制的示例代码
2017/09/21 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
原理深度解析Vue的响应式更新比React快
2020/04/04 Javascript
如何使用three.js 制作一个三维的推箱子游戏
2020/07/29 Javascript
python 一个figure上显示多个图像的实例
2019/07/08 Python
Python分析彩票记录并预测中奖号码过程详解
2019/07/09 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
Pycharm安装第三方库失败解决方案
2020/11/17 Python
用OpenCV进行年龄和性别检测的实现示例
2021/01/29 Python
岗位职责范本
2013/11/23 职场文书
国培远程培训感言
2014/03/08 职场文书
2014年五一促销活动方案
2014/03/09 职场文书
python开发的自动化运维工具ansible详解
2021/08/07 Python
java如何实现socket连接方法封装
2021/09/25 Java/Android
解析python中的jsonpath 提取器
2022/01/18 Python
Redis实现一个账号只能登录一个设备
2022/04/19 Redis