composer mysql_利用 Composer 一步一步构建自己的 PHP 框架(四)——使用 ORM

本文介绍了如何通过 Composer 安装并使用 Laravel 的 illuminate/database 包,集成 Eloquent ORM 到自建的 PHP 微框架中,详细阐述了配置数据库连接和使用 Eloquent 进行数据库操作的方法,帮助读者理解如何在 PHP 框架中实现数据库封装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用 Composer 一步一步构建自己的 PHP 框架(四)——使用 ORM

2014-10-16 / 阅读数:65457 / 分类: PHP

回顾

经过前三篇文章 基础准备 、 构建路由 和 设计 MVC ,我们已经得到了一个结构比较完整的 MVC 架构的 PHP 微框架,但是距离一个真正能够上手使用的框架还差一样东西: 数据库封装 ,本篇就将讲述如何集成一个 ORM Composer 包 。

本篇是本系列最后一篇,接下来我可能会以 让我们开了又开的 Composer 包 为系列标题分享一些体验和感悟,将主要发表在本站上。

正文

我们选择 Laravel 的 illuminate/database 作为我们的 ORM 包。我试用了几个著名的 ORM,发现还是 Laravel 的 Eloquent 好用!让我们开心的 ORM,开了又开! :-D

在本系列教程里,每一个 Composer 包都要满足以下基本要求:

原生依赖 Composer 进行管理

在好用的基础上尽量简单(比如我们那个超简单的路由包)

尽量新,用上 PHP 的新特性

说到 PHP 的新特性,有句题外话。 PHP5.3 引入了命名空间,这是规划在 PHP6 中的功能,所以 PHP5.3 在一定程度上其实就是 PHP6 ,PHP 的下一个版本是 PHP7 ,即将发布,主要贡献者是大名鼎鼎的 鸟哥 @Laruence 。另外本台前方记者(就是我)刚刚从微博发来报道,鸟哥正在放大招,制造传说中 PHP7 on JIT ,我大 PHP 的历史车轮是无法阻挡的哈哈哈!:-P

安装 illuminate/database

给 composer.json 增加一个 require 项:

"illuminate/database": "*"

运行 composer update ,等待安装完成。

使用 Eloquent

修改 public/index.php 为:

use Illuminate\Database\Capsule\Manager as Capsule;

// Autoload 自动载入

require '../vendor/autoload.php';

// Eloquent ORM

$capsule = new Capsule;

$capsule->addConnection(require '../config/database.php');

$capsule->bootEloquent();

// 路由配置

require '../config/routes.php';

新增 config/database.php (注意替换数据库密码):

return [

'driver' => 'mysql',

'host' => 'localhost',

'database' => 'mffc',

'username' => 'root',

'password' => 'password',

'charset' => 'utf8',

'collation' => 'utf8_general_ci',

'prefix' => ''

];

修改 models/Article.php :

/**

* Article Model

*/

class Article extends Illuminate\Database\Eloquent\Model

{

public $timestamps = false;

}

controllers/HomeController.php 无需改动。

刷新,页面依旧:

ae16e9987c6e43afd4ee375a9f37a10d.png

恭喜你!Eloquent 使用成功!

Eloquent 更多用法

Eloquent 异常强大 ,可以说是 Laravel 中 最特别 、 最有价值 的部分。

像 HomeController 中调用的 Article::first() ,之前用了十几行代码,现在什么都不用干,继承一个类就行了。

其他著名 ORM

还有很多著名的 ORM 和 Datamapping(数据库迁移等) 包,参见: ORM and Datamapping

ORM 能够大幅提高提高开发效率,Eloquent 真乃神器也!

虽然 web 届各语言阵营都在不断推出新的所谓 快速开发框架 ,终归还是越来越像 Rails 。Eloquent 在表面上几乎是最像 Rails 的 ORM 的了,但是跟 Rails 不能比啊,Ruby 的超强面向对象特性可不是盖的。Laravel 作者 Taylor Otwell 接受采访时曾表示,Eloquent 是整个 Laravel 中最难实现的部分。我在调试的时候也发现, MFFC/vendor/illuminate/database/Illuminate/Database/Eloquent/Model.php 这个文件有 3000 多行......

目前建造一个丰满的可以上手使用的 PHP 框架的工作就算是基本完成了,接下来我会继续完善 MFFC 框架,让她更加丰富、好用!

以后可能会有 模板引擎、表单验证、发送邮件、权限体系管理、异步队列、视频音频处理(乱入:-D) 等内容,敬请关注还未出世的 让我们开了又开的 Composer 包 系列文章。

谢谢大家的阅读和陪伴!再见!

该项目已经演化成为一个成熟的轻量优雅的 PHP 框架 Pinatra。https://github.com/Pinatra/Pinatra

WRITTEN BY

9918749bb4d134e0a0a19c7c9d51aff8.png

程序员,Swift Contributor,正在写《iOS 可视化编程与 Auto Layout》。

评论:

17795660dc39be85b37e2e2a4b81fd6f.png

兔子

2020-06-19 15:25

想问一下,独立使用Eloquent怎么注册观察者呢?

User::observe(UserObserver::class);貌似不可以

User::updated(function ($user){log(‘updated’);});也不行

protected $dispatchesEvents = [

'saved' => UserSaved::class,

'deleted' => UserDeleted::class,

];

也不行,通通不会执行

貌似是因为

protected static function registerModelEvent($event, $callback)

{

if (isset(static::$dispatcher)) {

$name = static::class;

static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);

}

}

但static::$dispatcher从哪来呢,我在官方文档里也没有看到

f2eb4aff4d2bcce79de0c4ced545de54.png

2020-06-19 15:36

@兔子:观察者依赖 Laravel 核心架构,Dispatch 也只是 Symfony 提供的一个标准化协议,如果想使用观察者,建议直接用 Laravel

34964abfbd68db4666c77a8e7ef4098f.gif

34964abfbd68db4666c77a8e7ef4098f.gif

17795660dc39be85b37e2e2a4b81fd6f.png

兔子

2020-06-19 17:13

@JohnLui:大佬回复真快!!!

1、那您的pinatra现在也是不能做到数据监听吗?

2、如果我坚持这么做那么改写Eloquent的成本或许又太大了

3、既然Eloquent是基于doctrine/dbal实现,那我直接用doctrine/orm是不是也是一个解决方案,毕竟很多微服务不需要整个框架,能访问数据库就可以了(但原生PDO又略简单了),我看了doctrine/orm的文档,应该都没有特殊的外部依赖

f2eb4aff4d2bcce79de0c4ced545de54.png

2020-06-19 18:55

@兔子:不是改写 Eloquent,是要改造你的框架,最终就会搞出一个 Laravel 来。

Eloquent 不是基于 doctrine 的,这个信息你是从哪里看的.....

17795660dc39be85b37e2e2a4b81fd6f.png

兔子

2020-06-19 20:08

@JohnLui:抱歉,我忘记哪里看的了,或许是我看到有依赖就自己臆想的。。。我会加以改正的

另外,我知道我前面为什么没效果了

$id=UserModel::insertGetId(['name'=>'兔子']);  //无效

$user=UserModel::find($id);  //有效

$user->name='小兔子';

$user->update();                   //有效

UserModel::where('id','=',$id)->update(['name'=>'小白兔']);  //无效

大概的规律就是除了查询,所有操作都需要实例化模型对象后,里面已经存在数据,操作才有效,但insert比较特别

1、UserModel::insert($values);

2、$userModel=new UserModel();$userModel->insert($values);

两者都不行

3952c5af910d3fb96758ff34cd8f4b9c.png

笑的很甜丶

2019-08-30 16:57

个人觉得laravel的配置放在.env文件中是一个比较前卫的做法。希望博主也能采纳,不过像我这样的人建议多了,那恭喜博主你重新带着我们搭建了一遍laravel。哈哈

1ab6f1488feac548cf4ca75272f788f3.gif

7dfd52c5a119d28f886509a4996e0e49.gif

86e3f161a4bddf1e89870b8c4f4ca495.png

小龙

2019-02-17 21:59

多数据库怎么办??

86e3f161a4bddf1e89870b8c4f4ca495.png

小龙

2018-05-11 16:49

多谢老大,但这个怎么读写分离呢??  Eloquent 怎么读写分离

399d34acbca0e1510dbb714504bfe8e6.png

秃子Sir

2018-02-26 15:00

博主,我用illuminate/database的,我那个模型名字是User 但是它默认去找users表,因为我数据库中的表叫user,所以找不到。您遇到过吗,谢谢。

f2eb4aff4d2bcce79de0c4ced545de54.png

2018-02-26 15:04

@秃子Sir:可以手动指定表名。

399d34acbca0e1510dbb714504bfe8e6.png

秃子Sir

2018-02-26 15:12

@JohnLui:嗯嗯。博主,我是大学生可能有些知识还很匮乏,这个问题解决了,我比较好奇一个问题哈,就是lavaral中的illuminate/database,是lavaral框架的人自己写的,还是他们集成过来的,还有用不用深究这个illuminate/database啥的,还有就是能不能给我个qq和微信联系方式,有时间好好请教你。

399d34acbca0e1510dbb714504bfe8e6.png

秃子Sir

2018-04-10 16:51

@JohnLui:博主,

怎么解决自动加载的那个类,使用命名空间的问题啊,就是您讲的这个例子,自动加载的类,没有命名空间,那如何才能支持命名空间呢。

b7cb32d104ce30e933a69419d22ca61e.png

2017-04-25 16:51

Fatal error: Uncaught Error: Class 'Illuminate\Database\Capsule\Manager' not found in G:\Lee\phpstudy\laravel\public\index.php:4 Stack trace: #0 {main} thrown in G:\Lee\phpstudy\laravel\public\index.php on line 4

bdc3550ba4c31754d388e0f8bffe54c0.gif

bdc3550ba4c31754d388e0f8bffe54c0.gif

bdc3550ba4c31754d388e0f8bffe54c0.gif

bdc3550ba4c31754d388e0f8bffe54c0.gif   这是啥错误啊  大佬

17795660dc39be85b37e2e2a4b81fd6f.png

taozi

2017-03-15 14:22

请问楼主,如果同时要操作两套数据库怎么解决呢?谢谢

17795660dc39be85b37e2e2a4b81fd6f.png

豆豆

2016-11-22 12:07

加上了ORM  , 好像分页不能用

068ee151c44f347507d42615a519b28e.png

十一

2016-08-27 17:59

orm有了  laravel 的 view 能够单独出来么?

8e499d49ac7825e666eb784052f149fe.png

ikodota

2016-07-05 10:53

eloquent 如何使用 master-slaver?

17795660dc39be85b37e2e2a4b81fd6f.png

Li

2016-06-03 11:58

博主 单独使用这个包怎么用事务?Laravel中是继承自DB门面的,这包里方法吗

17795660dc39be85b37e2e2a4b81fd6f.png

Li

2016-06-03 16:18

@Li:$capsule = new Capsule();

....

$aaa = $capsule->getConnection()->getPdo();

$aaa->beginTransaction();

可以这样开启事务,$capsule这个最好是实例化在一个公用方法中

86e3f161a4bddf1e89870b8c4f4ca495.png

小龙

2018-05-11 17:03

@Li:是啊,事务兄弟怎么弄?

17795660dc39be85b37e2e2a4b81fd6f.png

skylar

2019-04-11 05:13

@小龙:https://github.com/illuminate/database

hi,你好,我也遇到了这个问题,查到这个地方,最后解决了。如果你还需要的。:)

25779ad73b868080f3cf445ae1c19172.png

wenco

2019-09-30 09:47

@skylar:

a0542f03c517b09fdc8eee2307b1976a.gif所以这个仓库哪里说了关于事务的东西了?

65f5da31654ce2458699b40573006e09.png

拉风的男人

2016-02-26 22:09

Fatal error: Call to a member function connection() on null in /Users/admin/www/test/vendor/illuminate/database/Eloquent/Model.php on line 3277 这是什么原因导致的呢

17795660dc39be85b37e2e2a4b81fd6f.png

summer

2017-12-11 15:52

@拉风的男人:要在路由前面引入Eloquent

例如:

$capsule = new Capsule;

$capsule->addConnection(require dirname(__FILE__).'/config/database.php');

$capsule->bootEloquent();

//路由配置

require 'config/routes.php';

c196f3ffea87769bfe938cedcab91021.png

laoyao

2015-12-28 01:13

膜拜

3a910313350b50a7048ee62c428a1214.png

2015-11-27 10:35

117f2b7bb6ac767376907ed832575d7e.gif

请教下博主:这个ORM操作数据库和Zend、THINKPHP之类框架的insert select等方法操作差不多,感觉还略繁琐先预赋值后save creat,性能方面差别大?

17795660dc39be85b37e2e2a4b81fd6f.png

du5307

2015-09-05 22:29

按着lz的教程做了一遍,真心点赞~灰常感谢~~现在开始下一个系列~

17795660dc39be85b37e2e2a4b81fd6f.png

2015-07-13 17:14

为什么要在表后面加s呢

17795660dc39be85b37e2e2a4b81fd6f.png

efans

2015-07-08 18:29

请教下,单独使用这个orm的话,如何使用数据库事务?

use Illuminate\Support\Facades\DB;

...

DB::beginTransaction();

...

DB::commit();

这样居然不行,报错

Call to a member function beginTransaction() on a non-object in vendor/illuminate/support/Illuminate/Support/Facades/Facade.php on line 205

17795660dc39be85b37e2e2a4b81fd6f.png

skylar

2019-04-11 05:12

@efans:https://github.com/illuminate/database

hi,我也在做这个处理,刚好看到了这个问题的处理。如果还需要的话!~

17795660dc39be85b37e2e2a4b81fd6f.png

aha

2015-07-01 12:08

楼主可以用doctrine2来讲讲嘛?

17795660dc39be85b37e2e2a4b81fd6f.png

龙圆

2015-05-04 16:56

博主 请问 我执行composer update 怎么就是不行呢?

[Composer\Downloader\TransportException]

The "http://pkg.phpcomposer.com/repo/packagist/p/noahbuscher/macaw.json" file could not be downloaded: failed to open stream: HTTP request failed!

f2eb4aff4d2bcce79de0c4ced545de54.png

2015-05-04 17:39

@龙圆:中国镜像不稳定

43e2aee7ee94ca4aa83e70f1cc1674ad.gif

43e2aee7ee94ca4aa83e70f1cc1674ad.gif

17795660dc39be85b37e2e2a4b81fd6f.png

bruce

2015-08-05 13:20

@JohnLui:自从用了日本镜像 稳如狗 不爱国的可以用

89c3f9acae87ed5658635e25ec3449ed.gif

c0c6c3586a15c5b78105a0dffe686507.png

roy

2015-04-19 22:49

请教博主:请问rails这么强大,先进,为什么还会出来那么多模仿rails的PHP框架,直接都用rails不就好了吗?模仿的那么累,那么辛苦还是没有rails强大好用。

f2eb4aff4d2bcce79de0c4ced545de54.png

2015-04-19 22:56

@roy:Rails 强大,但是也有大规模工程化的致命弱点:难于部署、特性过于强大导致极易内存泄露、官方实现质量较差、性能极差导致无法承载大量用户。Rails 走到了“功能强大”的极端。

1 2

发表评论:

昵称

邮件地址 (选填)

个人主页 (选填)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值