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 删除一个目录及目录下的所有文件的函数代码
May 26 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
Aug 31 PHP
php遍历目录输出目录及其下的所有文件示例
Jan 27 PHP
PHP翻页跳转功能实现方法
Nov 30 PHP
使用Composer安装Yii框架的方法
Mar 15 PHP
PHP实现JS中escape与unescape的方法
Jul 11 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
Sep 11 PHP
用php和jQuery来实现“顶”和“踩”的投票功能
Oct 13 PHP
PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function
Feb 05 PHP
TP5框架实现上传多张图片的方法分析
Mar 29 PHP
php中加密解密DES类的简单使用方法示例
Mar 26 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基础学习之变量的使用
2011/06/09 PHP
php实现图片缩放功能类
2013/12/18 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
JSON序列化与解析原生JS方法且IE6和chrome测试通过
2013/09/05 Javascript
文本框水印提示效果的简单实现代码
2014/02/22 Javascript
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
用原生js做个简单的滑动效果的回到顶部
2014/10/15 Javascript
js脚本实现数据去重
2014/11/27 Javascript
基于javascript实现窗口抖动效果
2016/01/03 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
2016/04/01 Javascript
javascript实现粘贴qq截图功能(clipboardData)
2016/05/29 Javascript
js 能实现监听F5页面刷新子iframe 而父页面不刷新的方法
2016/11/09 Javascript
完美解决jQuery fancybox ie 无法显示关闭按钮的问题
2016/11/29 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
jQuery EasyUI tree增加搜索功能的实现方法
2017/04/27 jQuery
JS造成内存泄漏的几种情况实例分析
2020/03/02 Javascript
详解node.js 事件循环
2020/07/22 Javascript
浅谈JSON5解决了JSON的两大痛点
2020/12/14 Javascript
token 机制和实现方式
2020/12/15 Javascript
Python中的二维数组实例(list与numpy.array)
2018/04/13 Python
python操作kafka实践的示例代码
2019/06/19 Python
Tensorflow 卷积的梯度反向传播过程
2020/02/10 Python
python实现在内存中读写str和二进制数据代码
2020/04/24 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
2020/06/15 Python
幼师岗位求职简历的自荐信格式
2013/09/21 职场文书
皮肤科医师岗位职责
2013/12/04 职场文书
大学四年规划书范文
2013/12/27 职场文书
《这儿真好》教学反思
2014/02/22 职场文书
低碳环保倡议书
2014/04/14 职场文书
乡镇群众路线专项整治方案
2014/11/03 职场文书
2014年保密工作总结
2014/11/22 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
2015学生会文艺部工作总结
2015/04/03 职场文书
2015年精神文明建设工作总结
2015/04/21 职场文书
《生物入侵者》教学反思
2016/02/16 职场文书
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python