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写的带缓存数据功能的mysqli类
Sep 06 PHP
探讨方法的重写(覆载)详解
Jun 08 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
Nov 25 PHP
php实现无限级分类
Dec 24 PHP
php+mysqli事务控制实现银行转账实例
Jan 29 PHP
php抽象类使用要点与注意事项分析
Feb 09 PHP
详解WordPress中简码格式标签编写的基本方法
Dec 22 PHP
Zend Framework开发入门经典教程
Mar 23 PHP
php注册审核重点解析(数据访问)
May 23 PHP
php获取ajax的headers方法与内容实例
Dec 27 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
Dec 21 PHP
PHP引擎php.ini参数优化深入讲解
Mar 24 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
如何在Ubuntu下启动Apache的Rewrite功能
2013/07/05 PHP
php查看请求头信息获取远程图片大小的方法分享
2013/12/25 PHP
PHP调用VC编写的COM组件实例
2014/03/29 PHP
详解关于php的xdebug配置(编辑器vscode)
2019/01/29 PHP
css动画效果之animation的常用样式
2021/03/09 HTML / CSS
Web跨浏览器进程通信(Web跨域)
2013/04/17 Javascript
js中typeof的用法汇总
2013/12/12 Javascript
Egret引擎开发指南之创建项目
2014/09/03 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
javascript实现控制div颜色
2015/07/07 Javascript
设计模式中的facade外观模式在JavaScript开发中的运用
2016/05/18 Javascript
js 基础篇必看(点击事件轮播图的简单实现)
2016/08/20 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
微信小程序实现弹出层效果
2020/05/26 Javascript
webpack-url-loader 解决项目中图片打包路径问题
2019/02/15 Javascript
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
Vue.js组件props数据验证实现详解
2019/10/19 Javascript
Vue 组件的挂载与父子组件的传值实例
2020/09/02 Javascript
Js实现粘贴上传图片的原理及示例
2020/12/09 Javascript
Jquery+javascript实现支付网页数字键盘
2020/12/21 jQuery
[57:38]2018DOTA2亚洲邀请赛3月30日 小组赛A组 OpTic VS OG
2018/03/31 DOTA
python正则表达式抓取成语网站
2013/11/20 Python
python socket 超时设置 errno 10054
2014/07/01 Python
轻松实现TensorFlow微信跳一跳的AI
2018/01/05 Python
flask使用session保存登录状态及拦截未登录请求代码
2018/01/19 Python
pycharm 安装JPype的教程
2019/08/08 Python
python实现简单成绩录入系统
2019/09/19 Python
keras 多gpu并行运行案例
2020/06/10 Python
Python页面加载的等待方式总结
2021/02/28 Python
面向对象编程OOP的优点
2013/01/22 面试题
个人借款协议书范本
2014/11/17 职场文书
小学重阳节活动总结
2015/03/24 职场文书
2015年销售内勤工作总结
2015/04/27 职场文书
2015年生产部工作总结范文
2015/05/25 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS
输入框跟随文字内容适配宽实现示例
2022/08/14 Javascript