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 相关文章推荐
MySql 按时间段查询数据方法(实例说明)
Nov 02 PHP
PHP 字符串正则替换函数preg_replace使用说明
Jul 15 PHP
需要注意的几个PHP漏洞小结
Feb 05 PHP
php检测iis环境是否支持htaccess的方法
Feb 18 PHP
phpphp图片采集后按原路径保存图片示例
Feb 18 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
Aug 19 PHP
提高php编程效率技巧
Aug 13 PHP
学习php设计模式 php实现原型模式(prototype)
Dec 07 PHP
PHP实现文件上传和多文件上传
Dec 24 PHP
php+jQuery递归调用POST循环请求示例
Oct 14 PHP
在thinkphp5.0路径中实现去除index.php的方式
Oct 16 PHP
Yii 框架入口脚本示例分析
May 19 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按百分比生成缩略图的代码分享
2014/05/10 PHP
php插入mysql数据返回id的方法
2018/05/31 PHP
Laravel5.4框架使用socialite实现github登录的方法
2019/03/20 PHP
ASP.NET jQuery 实例4(复制TextBox的文本到本地剪贴板上)
2012/01/13 Javascript
JS操作图片(增,删,改) 例子
2013/04/17 Javascript
javascript实现汉字转拼音代码分享
2015/04/20 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
vue动态生成dom并且自动绑定事件
2017/04/19 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
JavaScrip关于创建常量的知识点
2017/12/07 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
jQuery实现轮播图及其原理详解
2020/04/12 jQuery
微信小程序如何获取手机验证码
2018/11/04 Javascript
JQuery常见节点操作实例分析
2019/05/15 jQuery
微信小程序点击列表跳转到对应详情页过程解析
2019/09/26 Javascript
Vue性能优化的方法
2020/07/30 Javascript
vue 内联样式style中的background用法说明
2020/08/05 Javascript
python查询mysql中文乱码问题
2014/11/09 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
DataFrame中的object转换成float的方法
2018/04/10 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
2019/08/02 Python
使用Python调取任意数字资产钱包余额功能
2019/08/15 Python
pygame实现非图片按钮效果
2019/10/29 Python
python中字典增加和删除使用方法
2020/09/30 Python
canvas使用注意点总结
2013/07/19 HTML / CSS
HTML5梦幻之旅——炫丽的流星雨效果实现过程
2013/08/06 HTML / CSS
欧洲领先的火车票和大巴票预订平台:Trainline
2018/12/26 全球购物
中东最大的在线宠物店:Dubai Pet Food
2020/06/11 全球购物
最新大学生自我评价
2013/09/24 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
会议开场欢迎词
2014/01/15 职场文书
自习课吵闹检讨书范文
2014/09/26 职场文书
结婚仪式主持词
2015/06/29 职场文书
十大最强妖精系宝可梦,哲尔尼亚斯实力最强,第五被称为大力士
2022/03/18 日漫