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 日期时间函数的高级应用技巧
Oct 10 PHP
PHP数组排序函数合集 以及它们之间的联系分析
Jun 27 PHP
php使用curl存储cookie的示例
Mar 31 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
May 19 PHP
php生成html文件方法总结
Dec 01 PHP
详解PHP数组赋值方法
Nov 07 PHP
php进行ip地址掩码运算处理的方法
Jul 11 PHP
PHP三种方式实现链式操作详解
Jan 21 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
Mar 28 PHP
PHP+jQuery实现滚屏无刷新动态加载数据功能详解
May 04 PHP
详解php反序列化
Jun 10 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使用glob函数遍历目录或文件夹的方法
2014/12/16 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
2015/08/21 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
php pdo操作数据库示例
2017/03/10 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
jscript之Open an Excel Spreadsheet
2007/06/13 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
javascript仿php的print_r函数输出json数据
2013/09/13 Javascript
JS实现匀速运动的代码实例
2013/11/29 Javascript
js 通用订单代码
2013/12/23 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
js获取域名的方法
2015/01/27 Javascript
使用Browserify配合jQuery进行编程的超级指南
2015/07/28 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
video.js使用改变ui过程
2017/03/05 Javascript
详解Vue This$Store总结
2018/12/17 Javascript
vue如何限制只能输入正负数及小数
2019/07/04 Javascript
layui表单验证select下拉框实现验证的方法
2019/09/05 Javascript
Python构建XML树结构的方法示例
2017/06/30 Python
python实现将一维列表转换为多维列表(numpy+reshape)
2019/11/29 Python
出纳的岗位职责
2013/11/09 职场文书
公司周年庆典邀请函
2014/01/12 职场文书
2014年综治宣传月活动总结
2014/04/28 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
单位消防安全责任书
2014/07/23 职场文书
民间借贷协议书范本
2014/10/01 职场文书
党员干部作风建设思想汇报范文
2014/10/25 职场文书
谢师宴答谢词
2015/01/05 职场文书
2015国际残疾人日活动总结
2015/03/24 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
会议主持人开场白台词
2015/05/28 职场文书
七一表彰大会简报
2015/07/20 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
区域销售大会开幕词
2016/03/04 职场文书
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang