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中die(),exit(),return的区别
Jun 20 PHP
ThinkPHP3.1数据CURD操作快速入门
Jun 19 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
Oct 26 PHP
php求一个网段开始与结束IP地址的方法
Jul 09 PHP
PHP会话处理的10个函数
Aug 11 PHP
学习php设计模式 php实现单例模式(singleton)
Dec 07 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
Oct 10 PHP
php把时间戳转换成多少时间之前函数的实例
Nov 16 PHP
PHP使用微信开发模式实现搜索已发送图文及匹配关键字回复的方法
Sep 13 PHP
PHP实现QQ登录的开原理和实现过程
Feb 04 PHP
PHP+Ajax实现的博客文章添加类别功能示例
Mar 29 PHP
php实现有序数组旋转后寻找最小值方法
Sep 27 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
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
php使用google地图应用实例
2014/12/31 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
Laravel手动分页实现方法详解
2016/10/09 PHP
php ajax数据传输和响应方法
2018/08/21 PHP
浅析PHP中json_encode与json_decode的区别
2020/07/15 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
JS OOP包机制,类创建的方法定义
2009/11/02 Javascript
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
2013/04/28 Javascript
js为数字添加逗号并格式化数字的代码
2013/08/23 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
2016/05/20 Javascript
AngularJS基础 ng-include 指令简单示例
2016/08/01 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
基于express中路由规则及获取请求参数的方法
2018/03/12 Javascript
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
2018/08/31 Javascript
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
2018/12/13 Javascript
vue实现点击追加选中样式效果
2019/11/01 Javascript
Python设计模式之命令模式原理与用法实例分析
2019/01/11 Python
Python-Seaborn热图绘制的实现方法
2019/07/15 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
Python3直接爬取图片URL并保存示例
2019/12/18 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
2020/04/01 Python
python 绘制国旗的示例
2020/09/27 Python
解决python 执行shell命令无法获取返回值的问题
2020/12/05 Python
Amaze UI 文件选择域的示例代码
2020/08/26 HTML / CSS
卫校毕业生自我鉴定
2013/10/31 职场文书
汽车专业大学生职业生涯规划范文
2014/01/07 职场文书
《春笋》教学反思
2014/04/15 职场文书
中学生自我评价范文
2015/03/03 职场文书
校长新学期寄语2016
2015/12/04 职场文书
2019年英语版感谢信(8篇)
2019/09/29 职场文书