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
WINXP下apache+php4+mysql
Nov 25 PHP
PHP教程 预定义变量
Oct 23 PHP
解析smarty模板中类似for的功能实现
Jun 18 PHP
smarty模板局部缓存方法使用示例
Jun 17 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
Sep 22 PHP
php版微信公众平台开发之验证步骤实例详解
Sep 23 PHP
php array_values 返回数组的值实例详解
Nov 17 PHP
Yii2中hasOne、hasMany及多对多关联查询的用法详解
Feb 15 PHP
php文件包含目录配置open_basedir的使用与性能详解
Apr 03 PHP
php中的explode()函数实例介绍
Jan 18 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
Mar 09 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安全编程之加密功能
2006/10/09 PHP
用session做客户验证时的注意事项
2006/10/09 PHP
APMServ使用说明
2006/10/23 PHP
如何在symfony中导出为CSV文件中的数据
2011/10/06 PHP
详解PHP的Yii框架中日志的相关配置及使用
2015/12/08 PHP
PHP使用内置函数生成图片的方法详解
2016/05/09 PHP
理解Javascript_06_理解对象的创建过程
2010/10/15 Javascript
Jquery.Form 异步提交表单的简单实例
2014/03/03 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
前端轻量级MVC框架CanJS详解
2014/09/26 Javascript
javascript中slice(),splice(),split(),substring(),substr()使用方法
2015/03/13 Javascript
js密码强度校验
2015/11/10 Javascript
AngularJS 中的Promise --- $q服务详解
2016/09/14 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
javascript中的后退和刷新实现方法
2016/11/10 Javascript
js脚本编写简单刷票投票系统
2017/06/27 Javascript
React中的render何时执行过程
2018/04/13 Javascript
node thread.sleep实现示例
2018/06/20 Javascript
快速对接payjq的个人微信支付接口过程解析
2019/08/15 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
vue+elementui 对话框取消 表单验证重置示例
2019/10/29 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
2019/12/20 Javascript
使用Python的Bottle框架写一个简单的服务接口的示例
2015/08/25 Python
python使用百度文字识别功能方法详解
2019/07/23 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
python3 实现函数写文件路径的正确方法
2019/11/27 Python
Selenium 滚动页面至元素可见的方法
2020/03/18 Python
浅谈h5自定义audio(问题及解决)
2016/08/19 HTML / CSS
仓管员岗位职责范文
2013/11/08 职场文书
优秀员工获奖感言
2014/03/01 职场文书
2014年文艺部工作总结
2014/11/17 职场文书
高三复习计划
2015/01/19 职场文书
社区党员干部承诺书
2015/05/04 职场文书
《折线统计图》教学反思
2016/02/22 职场文书
深入浅析Django MTV模式
2021/09/04 Python
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang