利用 Composer 一步一步构建自己的 PHP 框架(四)——使用 ORM
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer
回顾
经过前三篇文章 基础准备 、 构建路由 和 设计 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 为:
<?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 (注意替换数据库密码):
<?php
return [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'mffc',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => ''
];
修改 models/Article.php :
<?php
/**
* Article Model
*/
class Article extends Illuminate\Database\Eloquent\Model
{
public $timestamps = false;
}
controllers/HomeController.php 无需改动。
刷新,页面依旧:
恭喜你!Eloquent 使用成功!
Eloquent 更多用法
Eloquent 异常强大 ,可以说是 Laravel 中 最特别 、 最有价值 的部分。
像 HomeController 中调用的 Article::first() ,之前用了十几行代码,现在什么都不用干,继承一个类就行了。
Eloquent 更多用法参见:Eloquent ORM 中文文档
其他著名 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
新文章:利用 Composer 完善自己的 PHP 框架系列
评论:
2020-06-19 15:36
2020-06-19 17:13
1、那您的pinatra现在也是不能做到数据监听吗?
2、如果我坚持这么做那么改写Eloquent的成本或许又太大了
3、既然Eloquent是基于doctrine/dbal实现,那我直接用doctrine/orm是不是也是一个解决方案,毕竟很多微服务不需要整个框架,能访问数据库就可以了(但原生PDO又略简单了),我看了doctrine/orm的文档,应该都没有特殊的外部依赖
2020-06-19 18:55
Eloquent 不是基于 doctrine 的,这个信息你是从哪里看的.....
2020-06-19 20:08
另外,我知道我前面为什么没效果了
$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);
两者都不行
2019-08-30 16:57
2018-02-26 15:00
2016-02-26 22:09
2015-07-08 18:29
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
2015-05-04 16:56
[Composer\Downloader\TransportException]
The "https://pkg.phpcomposer.com/repo/packagist/p/noahbuscher/macaw.json" file could not be downloaded: failed to open stream: HTTP request failed!
2015-04-19 22:49
2014-12-12 10:54
但是 有个疑问就是 orm 这部分 怎么调用 sqlite 和其他类型的数据库呢
我把配置文件 改成了 laravel 里 sqlite 的部分
但是 Call to a member function getConnection() on a non-object 报错
2014-11-03 23:07
请问这个 php 的版本是什么呢?
我照着教程的步骤,会出现错误:
```
Warning: preg_match(): Compilation failed: unmatched parentheses at offset 5 in C:\Users\Deben\Documents\www-myfw\vendor\codingbean\macaw\Macaw.php on line 117
```
并且上一步的路由设置也一定要加 "/" 才行,我的环境是 wamp5,请问你这个 php 是什么版本的呢?
2014-10-29 10:05
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 32 bytes) in phar:https:///Applications/MAMP/htdocs/composer/composer.phar/src/Composer/DependencyResolver/RuleWatchNode.php on line 40
好像是运行内存不足,但是我在 php.ini 里面,已经给 memory_limit 设置为 1024 了
我的json 文件为
{
"require": {
"codingbean/macaw": "dev-master",
"illuminate/database": "*"
},
"autoload": {
"classmap": [
"app/controllers",
"app/models"
]
},
"repositories": [
{ "packagist": false },
{
"type": "composer",
"url": "https://218.244.132.204/proxy/packagist"
}
]
}
请麻烦帮忙看一下,继续看您的文章学习 ,谢谢
2014-10-29 12:23
而且你改的php.ini不一定对,看这里:https://segmentfault.com/q/1010000000729459/a-1020000000729473
2020-06-19 15:25
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从哪来呢,我在官方文档里也没有看到