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单件模式结合命令链模式使用说明
Sep 07 PHP
php 破解防盗链图片函数
Dec 09 PHP
php快速url重写 更新版[需php 5.30以上]
Apr 20 PHP
关于UEditor编辑器远程图片上传失败的解决办法
Aug 31 PHP
微信扫描二维码登录网站代码示例
Dec 30 PHP
php调用c接口无错版介绍
Mar 11 PHP
Laravel框架学习笔记(一)环境搭建
Oct 15 PHP
php计算整个mysql数据库大小的方法
Jun 19 PHP
php模板引擎技术简单实现
Mar 15 PHP
php 使用 __call实现重载功能示例
Nov 18 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
Feb 23 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 $_SERVER[&quot;REQUEST_URI&quot;]获取值的通用解决方法
2010/06/21 PHP
php目录操作实例代码
2014/02/21 PHP
thinkphp连贯操作实例分析
2014/11/22 PHP
php使用cookie保存登录用户名的方法
2015/01/26 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
总结PHP中DateTime的常用方法
2016/08/11 PHP
php实现分页功能的详细实例方法
2019/09/29 PHP
PHP 枚举类型的管理与设计知识点总结
2020/02/13 PHP
javscript对象原型的一些看法
2010/09/19 Javascript
ECMAScript 创建自己的js类库
2012/11/22 Javascript
JavaScript获取flash对象与网上的有所不同
2014/04/21 Javascript
QQ登录背景闪动效果附效果演示源码下载
2015/09/22 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
2016/12/13 Javascript
使用Javascript判断浏览器终端设备(PC、IOS(iphone)、Android)
2017/01/04 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
2017/03/02 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
利用纯JS实现像素逐渐显示的方法示例
2017/08/14 Javascript
Nodejs连接mysql并实现增、删、改、查操作的方法详解
2018/01/04 NodeJs
jQuery实现判断上传图片类型和大小的方法示例
2018/04/11 jQuery
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
vue vant Area组件使用详解
2019/12/09 Javascript
PyTorch CNN实战之MNIST手写数字识别示例
2018/05/29 Python
python 自动去除空行的实例
2018/07/24 Python
python简单贪吃蛇开发
2019/01/28 Python
Kali Linux安装ipython2 和 ipython3的方法
2019/07/11 Python
Django 解决model 反向引用中的related_name问题
2020/05/19 Python
Python 带星号(* 或 **)的函数参数详解
2021/02/23 Python
HTML5文档结构标签
2017/04/21 HTML / CSS
IFCHIC台湾:欧美国际设计师品牌
2019/05/18 全球购物
C语言编程练习
2012/04/02 面试题
调解员先进事迹材料
2014/02/07 职场文书
营销总监岗位职责范本
2014/02/26 职场文书
幼儿园个人师德总结
2015/02/06 职场文书
2015年街道除四害工作总结
2015/05/15 职场文书
小学四年级班主任工作经验交流材料
2015/11/02 职场文书
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL