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 相关文章推荐
超级实用的7个PHP代码片段分享
Jan 05 PHP
php模板函数 正则实现代码
Oct 15 PHP
一漂亮的PHP图片验证码实例
Mar 21 PHP
php文件上传简单实现方法
Jan 24 PHP
PHP实现在线阅读PDF文件的方法
Jun 17 PHP
PHP+JQUERY操作JSON实例
Mar 23 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
Jun 20 PHP
PHP基于cookie实现统计在线人数功能示例
Jan 16 PHP
Laravel向公共模板赋值方法总结
Jun 25 PHP
php生成HTML文件的类方法
Oct 11 PHP
php上传后台无法收到数据解决方法
Oct 28 PHP
PHP数组Key强制类型转换实现原理解析
Sep 01 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中的串行化变量和序列化对象
2006/09/05 PHP
php调用mysql存储过程
2007/02/14 PHP
php扩展ZF――Validate扩展
2008/01/10 PHP
ThinkPHP使用UTFWry地址库进行IP定位实例
2014/04/01 PHP
PHP+mysql+ajax轻量级聊天室实现方法详解
2016/10/17 PHP
Jquery 一次处理多个ajax请求的代码
2011/09/02 Javascript
3款实用的在线JS代码工具(国外)
2012/03/15 Javascript
js控制的回到页面顶端goTop的代码实现
2013/03/20 Javascript
jQuery输入城市查看地图使用介绍
2013/05/08 Javascript
使用JS CSS去除IE链接虚线框的三种方法
2013/11/14 Javascript
使用JavaScript的ActiveXObject对象检测应用程序是否安装的方法
2014/04/15 Javascript
javascript制作网页图片上实现下雨效果
2015/02/26 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
JQuery动态添加和删除表格行的方法
2015/03/09 Javascript
JS实现适合于后台使用的动画折叠菜单效果
2015/09/21 Javascript
js实现微博发布小功能
2017/01/12 Javascript
jQuery多选框选择数量限制方法
2017/02/08 Javascript
angular+ionic返回上一页并刷新页面
2017/08/08 Javascript
React中嵌套组件与被嵌套组件的通信过程
2018/07/11 Javascript
python数组过滤实现方法
2015/07/27 Python
Python实现购物车购物小程序
2018/04/18 Python
python去重,一个由dict组成的list的去重示例
2019/01/21 Python
Python 编程速成(推荐)
2019/04/15 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
如何基于python操作excel并获取内容
2019/12/24 Python
Python3爬虫发送请求的知识点实例
2020/07/30 Python
python palywright库基本使用
2021/01/21 Python
高中的职业生涯规划书
2013/12/28 职场文书
毕业生求职自荐信怎么写
2014/01/08 职场文书
致标枪运动员广播稿
2014/02/06 职场文书
五年级音乐教学反思
2014/02/06 职场文书
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
师范生求职自荐信
2014/06/14 职场文书
单位工作证明
2014/10/07 职场文书
湘江北去观后感
2015/06/15 职场文书
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技