刚开始用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模型中非静态方法也能静态调用的原理的更多相关文章

  1. "静态方法里仅仅能调用静态变量和静态方法"具体解释

    静态方法里能够调用静态方法和静态变量,同一时候也能调用非静态方法和非静态变量. public class Test { public Test() {}; public Test(int i) {th ...

  2. php静态调用非静态方法

    <?php /** * php静态调用非静态方法 * author: 百里 * Date: 2019/7/18 * Time: 17:28 */ function dump(...$var) { ...

  3. Laravel模型事件的实现原理详解

    模型事件在 Laravel 的世界中,你对 Eloquent 大多数操作都会或多或少的触发一些模型事件,下面这篇文章主要给大家介绍了关于Laravel模型事件的实现原理,文中通过示例代码介绍的非常详细 ...

  4. Laravel 模型事件入门

    Laravel 模型事件允许你监听模型生命周期内的多个关键点,甚至可以在阻止一个模型的保存或者删除. Laravel 模型事件文档 概述了如何使用钩子将对应事件与相关的事件类型关联起来,但是本文的主旨 ...

  5. Java中的静态方法和实例方法的调用的理解(不同的类下的方法调用)

    public class MethodCall { public static void main(String[] args) { Test.sayStatic(); Test test = new ...

  6. 在Delphi中静态调用DLL

    在Delphi中静态调用DLL top 调用一个DLL比写一个DLL要容易一些.首先给大家介绍的是静态调用方法,稍后将介绍动态调用方法,并就两种方法做一个比较.同样的,我们先举一个静态调用的例子. u ...

  7. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

  8. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  9. jQuery扩展两类函数(对象调用,静态调用)

    作者:zccst 先看小例子: $(function(){ //扩展方式1-通过对新调用 $.fn.each1=function(){ console.log("hehehehe$.fn.f ...

随机推荐

  1. oracle学习笔记(十) 查询练习(一)

    查询练习一 表创建 create table employee as select * from soctt.emp ; --记得授权 sysdba用户登录 grant select on scott ...

  2. Android应用图标尺寸以及drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)

    应用图标: L DPI ( Low Density Screen,120 DPI ),其图标大小为 36 x 36 px M DPI ( Medium Density Screen, 160 DPI ...

  3. Socket,Tcp,Http的关联

    下面的图表试图显示不同的TCP/IP和其他的协议在最初OSI模型中的位置: TCP/IP 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议 ...

  4. Hive_hdfs导入csv文件

    转自:Hive_hdfs csv导入hive demo   1 create csv file.student.csv 4,Rose,M,78,77,76 5,Mike,F,99,98,98 2 pu ...

  5. Oracle:Redhat 7.4+Oracle Rac 11.2.0.4 执行root.sh报错处理

    一.报错信息 二.原因分析 因为RHEL 7使用systemd而不是initd运行进程和重启进程,而root.sh通过传统的initd运行ohasd进程 三.解决办法 在RHEL 7中ohasd需要被 ...

  6. python中time、datetime模块的使用

    目录 python中time.datetime模块的使用 1.前言 2.time模块 1.时间格式转换图 2.常用方法 3.datetime模块 python中time.datetime模块的使用 1 ...

  7. 浅谈Vue下的components模板

    浅谈Vue下的components模板在我们越来越深入Vue时,我们会发现我们对HTML代码的工程量会越来越少,今天我们来谈谈Vue下的 components模板的 初步使用方法与 应用 我们先来简单 ...

  8. Sublime操作

    快速搭建HTML模版:左下角的纯文本编程HTML语言,然后输出!(感叹号)或者html:5,再按Tab键. 快速创建html标签: div#top>(div.top-left>div.li ...

  9. 离线安装python第三方库的实用方法:解决公司内网,服务器/电脑不能上网却需要安装python三方库问题(上:Windows环境中)

    问题描述: 公司的windows电脑是内网,今天需要安装一个Twisted库,用过的应该都晓得,很常见的异步库,但是仅仅依靠Pypi上下载下来的离线.whl安装包是不行的,linux服务器都是远程连接 ...

  10. pycharm 设置django server