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&amp;&amp;mysql)三
Oct 09 PHP
Ha0k 0.3 PHP 网页木马修改版
Oct 11 PHP
利用ThinkPHP内置的ThinkAjax实现异步传输技术的实现方法
Dec 19 PHP
PHP用身份证号获取星座和生肖的方法
Nov 07 PHP
php实现水仙花数的4个示例分享
Apr 08 PHP
php的SimpleXML方法读写XML接口文件实例解析
Jun 16 PHP
浅谈php优化需要注意的地方
Nov 27 PHP
深入理解PHP JSON数组与对象
Jul 19 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
Dec 21 PHP
jQuery ajax+PHP实现的级联下拉列表框功能示例
Feb 12 PHP
php查询内存信息操作示例
May 09 PHP
PHP实现统计代码行数小工具
Sep 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下使用以下代码连接并测试
2008/04/09 PHP
PHP程序员必须清楚的问题汇总
2014/12/18 PHP
centos 7.2下搭建LNMP环境教程
2016/11/20 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
laravel 输出最后执行sql 附:whereIn的使用方法
2019/10/10 PHP
extjs grid设置某列背景颜色和字体颜色的实现方法
2010/09/06 Javascript
jquery中prop()方法和attr()方法的区别浅析
2013/09/06 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
2013/12/02 Javascript
js获取下拉列表框中的value和text的值示例代码
2014/01/11 Javascript
Bootstrap入门书籍之(四)菜单、按钮及导航
2016/02/17 Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
2018/08/12 Javascript
解决vue A对象赋值给B对象,修改B属性会影响到A的问题
2018/09/25 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
javascript中的数据类型检测方法详解
2019/08/07 Javascript
谈谈JavaScript中的垃圾回收机制
2020/09/17 Javascript
Ajax获取node服务器数据的完整步骤
2020/09/20 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
[01:14:31]Secret vs VG 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
Python爬虫实例爬取网站搞笑段子
2017/11/08 Python
Python中django学习心得
2017/12/06 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
解决Tensorflow sess.run导致的内存溢出问题
2020/02/05 Python
Python基于内置库pytesseract实现图片验证码识别功能
2020/02/24 Python
使用python编写一个语音朗读闹钟功能的示例代码
2020/07/14 Python
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
西班牙灯具网上商店:Lampara.es
2018/06/05 全球购物
Kendra Scott官网:美国领先的时尚配饰品牌
2020/10/22 全球购物
新年团拜会主持词
2014/04/02 职场文书
电气工程及其自动化专业毕业生自荐信
2014/06/21 职场文书
鸦片战争观后感
2015/06/09 职场文书
学校运动会开幕词
2016/03/03 职场文书
Python Pandas知识点之缺失值处理详解
2021/05/11 Python
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL
python模板入门教程之flask Jinja
2022/04/11 Python