刚开始用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. VS2017安装使用Easyx时出现的问题及解决方法

    EasyX 是针对 Visual C++ 的绘图库,在初学 C 语言实现图形和游戏编程.图形学.分形学等需要绘图实践的领域有一定应用. EasyX 库在 Visual C++ 中模拟了 Turbo C ...

  2. LazyCoder修仙之路

    本人不才,没有高文凭,茹果本人的修仙[开发]之路能 ,走的很远,后来的人能看的上我 作品,有不足,和不对,帮帮我完善和理解.这也是我 学习笔记把!

  3. Vuex细说

    vuex 1,什么是 vuex? vuex 是一个专门为 vue.js 应用程序 开发的状态管理模式+库 它充当应用程序中所有组件的集中存储(数据状态) ,其规则确保状态只能以可预测的方式进行变更 并 ...

  4. Kotlin介绍(非原创)

    文章大纲 一.Kotlin简介二.Kotlin相比Java优势三.Kotlin与Java混合使用四.参考文章   一.Kotlin简介 1. 什么是Kotlin 安卓和Java,前者是最受欢迎的移动开 ...

  5. Android Studio compile error ---- enum constant INSTANT_RUN_REPLACEMENT does not

    原文:http://stackoverflow.com/questions/34868876/android-studio-compile-error-enum-constant-instant-ru ...

  6. 结对编程(Java实现)

    一.Github项目地址:https://github.com/qiannai/CreateArithmetic 二.PSP2.1表格: PSP2.1 Personal Software Proces ...

  7. mysql综合性练习

    题目描述 设定有一个数据库,里面有4张表: 学生表(student) 课程表(course) 成绩表(score) 教师信息表(teacher) 表结构如下: 表一_学生表(student) 属性名 ...

  8. 数据库 OR 运维 ____bayaim

    最近一直在思考,想想未来的道路和自己努力的方向.马云曾说过现在的年轻人缺少“慢下来”,只有人慢下来才能更好思考,想好方法和目标才更靠近才成功.如果,一直不停的努力,在错误的道路越走越远,势必会浪费时间 ...

  9. layui获取checkbox复选框值

    获取layui表单复选框已选中的数据 HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...

  10. CodeForces - 1228C(质因数分解+贡献法)

    题意 https://vjudge.net/problem/CodeForces-1228C 首先先介绍一些涉及到的定义: 定义prime(x)表示x的质因子集合.举例来说,prime(140)={2 ...