Laravel框架源码解析之模型Model原理与用法解析


Posted in PHP onMay 14, 2020

本文实例讲述了Laravel框架源码解析之模型Model原理与用法。分享给大家供大家参考,具体如下:

前言

提前预祝猿人们国庆快乐,吃好、喝好、玩好,我会在电视上看着你们。

根据单一责任开发原则来讲,在laravel的开发过程中每个表都应建立一个model对外服务和调用。类似于这样

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
 protected $table = 'users';
}

解析

Laravel的数据操作分两种

  • DB facade
  • Eloquent ORM

它们除了有各自的特色外,基本的数据操作都是通过 Illuminate\Database\Query\Builder 调用方法去完成整个SQL。你也可以帮Builder这个类作为整个SQL操作的基类。这个类涵盖了以下的操作方法(部分展示)

方法
public function select($columns = ['*'])
public function selectSub($query, $as)
public function selectRaw($expression, array $bindings = [])
public function fromSub($query, $as)
public function fromRaw($expression, $bindings = [])
public function addSelect($column)
public function distinct()
public function from($table)
public function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
public function joinWhere($table, $first, $operator, $second, $type = 'inner')
public function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
public function leftJoin($table, $first, $operator = null, $second = null)
public function where($column, $operator = null, $value = null, $boolean = 'and')
public function orWhere($column, $operator = null, $value = null)
public function whereRaw($sql, $bindings = [], $boolean = 'and')
public function whereIn($column, $values, $boolean = 'and', $not = false)
public function orWhereIn($column, $values)

可见有很多方法在中国laravel站或者官方文档上都没有体现,所以说就算要精通一款框架,不去看它的源码也是不行的。这个文件在你项目目录中的 vendor/laravel/framework/src/Illuminate/Database/Query 下,你可以自行去查看。

DB facade

正常情况下你可能会这样写一个操作

DB::table('user')->get();

这个操作首先经过laravel的门面指向文件,不过它并不在 app.php 中,而是通过内核直接加载,它在

Illuminate\Foundation\Application -> registerCoreContainerAliases()

被注册。门面直接调用 Illuminate\Database\DatabaseManager 类。

public function registerCoreContainerAliases()
{
  foreach ([
   ...
   'encrypter'   => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class],
   'db'     => [\Illuminate\Database\DatabaseManager::class],
   'db.connection'  => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
   'events'    => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
   'files'    => [\Illuminate\Filesystem\Filesystem::class],
   ....
  )
}

Illuminate\Database\DatabaseManager 内并没有太多的代码,大多都是处理数据库链接。当你使用 DB::table()时,会通过

public function __call($method, $parameters)
{
 return $this->connection()->$method(...$parameters);
}

转发,调用的是 Illuminate\Database\Connection ,用户处理 table() 方法,随后会通过 table() 方法指向 Illuminate\Database\Query 类,开头我们讲过这个类了,这里就不多说了,随后就是各种sql的拼接->执行sql->结束战斗

Laravel框架源码解析之模型Model原理与用法解析

Eloquent ORM

Eloquent ORM 与DB facade 类似,首先每个 Eloquent ORM 都需要继承父类 Illuminate\Database\Eloquent\Model
你大概会这样写

User::find(1)

父类是不存在这个方法的,它会通过

public static function __callStatic($method, $parameters)
{
 return (new static)->$method(...$parameters);
}

去转发请求调用。同理

User::get()

则是通过

public function __call($method, $parameters)
{
 if (in_array($method, ['increment', 'decrement'])) {
  return $this->$method(...$parameters);
 }
  
 return $this->newQuery()->$method(...$parameters);
}

去调用,这个方法最终以 new Builder() 而告终,

public function newEloquentBuilder($query)
{
 return new Builder($query);
}

最后我们到了 Illuminate\Database\Eloquent\Builder 文件下,这个类中涵盖了ORM的基本操作,例如find , findOrFail 等等。如果你在代码用到了get方法,抱歉,这里没有,它依旧会通过__call 方法将你的请求转发到 Illuminate\Database\Query\Builder 类中

$this->query->{$method}(...$parameters);

至此就完成了整个数据操作。

Laravel框架源码解析之模型Model原理与用法解析

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

PHP 相关文章推荐
php中大括号作用介绍
Mar 22 PHP
header中Content-Disposition的作用与使用方法
Jun 13 PHP
php的$_FILES的临时储存文件与回收机制实测过程
Jul 12 PHP
PHP生成等比缩略图类和自定义函数分享
Jun 25 PHP
用PHP解决的一个栈的面试题
Jul 02 PHP
THINKPHP项目开发中的日志记录实例分析
Dec 01 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
Sep 11 PHP
PHP实现根据数组的值进行分组的方法
Apr 20 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
Nov 17 PHP
PHP精确到毫秒秒杀倒计时实例详解
Mar 14 PHP
thinkPHP5框架实现多数据库连接,跨数据连接查询操作示例
May 29 PHP
Laravel手动返回错误码示例
Oct 22 PHP
Laravel框架源码解析之入口文件原理分析
May 14 #PHP
Laravel框架源码解析之反射的使用详解
May 14 #PHP
PHP 数组操作详解【遍历、指针、函数等】
May 13 #PHP
ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解
May 12 #PHP
php中用unset销毁变量并释放内存
May 10 #PHP
php屏蔽错误及提示的方法
May 10 #PHP
php判断数组是否为空的实例方法
May 10 #PHP
You might like
php 删除无限级目录与文件代码共享
2008/11/22 PHP
一些 PHP 管理系统程序中的后门
2009/08/05 PHP
php下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
ThinkPHP模板中判断volist循环的最后一条记录的验证方法
2014/07/01 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
Laravel 修改默认日志文件名称和位置的例子
2019/10/17 PHP
php + ajax 实现的写入数据库操作简单示例
2020/05/16 PHP
Jquery知识点一 Jquery的ready和Dom的onload的区别
2011/01/15 Javascript
jquery live()调用不存在的解决方法
2014/02/26 Javascript
jquery.uploadify插件在chrome浏览器频繁崩溃解决方法
2015/03/01 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
2015/03/02 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
jQuery弹簧插件编写基础之“又见弹窗”
2015/12/11 Javascript
nodejs使用express创建一个简单web应用
2017/03/31 NodeJs
在一般处理程序(ashx)中弹出js提示语
2017/08/16 Javascript
打字效果动画的4种实现方法(超简单)
2017/10/18 Javascript
Vue实现base64编码图片间的切换功能
2019/12/04 Javascript
[45:46]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS DT
2014/05/23 DOTA
python3.3实现乘法表示例
2014/02/07 Python
在pycharm中使用git版本管理以及同步github的方法
2019/01/16 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
Tensorflow设置显存自适应,显存比例的操作
2020/02/03 Python
python实现简单遗传算法
2020/09/18 Python
国际知名军事风格休闲装品牌:Alpha Industries(阿尔法工业)
2017/05/24 全球购物
Erwin Müller穆勒家居瑞士官网:您整个家庭的邮购公司
2019/12/28 全球购物
Ejb技术面试题
2015/04/29 面试题
英文版餐饮运营管理求职信
2013/11/06 职场文书
2015年幼儿园毕业感言
2014/02/12 职场文书
自我查摆剖析材料
2014/10/11 职场文书
团员个人年度总结
2015/02/26 职场文书
观后感开头
2015/06/19 职场文书
2016新党章学习心得体会
2016/01/15 职场文书
2016年公司“3.12”植树节活动总结
2016/03/16 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书
MYSQL 的10大经典优化案例场景实战
2021/09/14 MySQL
Python几种酷炫的进度条的方式
2022/04/11 Python