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版)
Oct 09 PHP
特转载一高手总结PHP学习资源和链接.
Dec 05 PHP
PHP中开发XML应用程序之基础篇 添加节点 删除节点 查询节点 查询节
Jul 09 PHP
PHP中使用foreach和引用导致程序BUG的问题介绍
Sep 05 PHP
分享一下贝贝成长进度的php代码
Sep 14 PHP
PHP连接MYSQL数据库实例代码
Jan 20 PHP
PHP Static延迟静态绑定用法分析
Mar 16 PHP
非常有用的9个PHP代码片段
Apr 06 PHP
简单理解PHP的面向对象编程方式
May 17 PHP
PHP判断JSON对象是否存在的方法(推荐)
Jul 06 PHP
使用laravel的migrate创建数据表的方法
Sep 30 PHP
PHP Trait功能与用法实例分析
Jun 03 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/03 咖啡文化
php使用百度翻译api示例分享
2014/01/31 PHP
php stripslashes和addslashes的区别
2014/02/03 PHP
php文件操作之小型留言本实例
2015/06/20 PHP
用jQuery技术实现Tab页界面之二
2009/09/21 Javascript
基于jquery的滚动新闻列表
2010/06/19 Javascript
js TextArea的选中区域处理
2010/12/28 Javascript
js图片预加载示例
2014/04/30 Javascript
jQuery常用数据处理方法小结
2015/02/20 Javascript
基于JavaScript代码实现自动生成表格
2016/06/15 Javascript
jQuery使用each方法与for语句遍历数组示例
2016/06/16 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
实用的Vue开发技巧
2019/05/30 Javascript
这样回答继承可能面试官更满意
2019/12/10 Javascript
解决Vue 刷新页面导航显示高亮位置不对问题
2019/12/25 Javascript
[03:52]DOTA2英雄基础教程 酒仙
2013/12/23 DOTA
[38:44]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第二局
2016/02/25 DOTA
python正则表达式中的括号匹配问题
2014/12/14 Python
在python的类中动态添加属性与生成对象
2016/09/17 Python
python3学习之Splash的安装与实例教程
2018/07/09 Python
python之文件读取一行一行的方法
2018/07/12 Python
Python使用sax模块解析XML文件示例
2019/04/04 Python
Pandas之read_csv()读取文件跳过报错行的解决
2020/04/21 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
web字体加载方案优化小结
2019/11/29 HTML / CSS
英国领先的办公用品供应商:Viking
2016/08/01 全球购物
促销活动总结报告
2014/04/26 职场文书
销售活动策划方案
2014/08/26 职场文书
党员干部民主生活会议批评与自我批评材料
2014/09/20 职场文书
2014年小学教师工作自我评价
2014/09/22 职场文书
基层党员对照检查材料
2014/09/24 职场文书
2014年最新离婚协议书范本
2014/10/11 职场文书
2014年电厂个人工作总结
2014/11/27 职场文书
故宫导游词
2015/01/31 职场文书
爱晚亭导游词
2015/02/09 职场文书
销售助理岗位职责
2015/02/11 职场文书