Codeigniter 4 发布已经有一段时间了,作为一个老牌的,而且是当初入门重度使用的 PHP 框架,还是有特别的感情。
CodeIgniter 4 做了比较大的更改,更加现代化了,与 Composer 集成更加紧密,仅支持 PHP 7.2 以上版本,但是又保持了核心理念,简单,快速,基本所有的组件都是自身实现,对第三方依赖少,在简单的同时又提供非常多的功能。
CodeIgniter 4 对数据库操作也扩展了功能,提供了 Model 跟 Entity 类,对数据库操作基本是每个框架最核心的功能,虽然 CodeIgniter 4 扩展了数据库操作的功能,但是跟 Laravel 的 Eloquent ORM 还是没法比,而 Eloquent ORM 可以说是我最钟爱的,基本可以说无出其右,也是 Laravel 仅有的亮点。
Eloquent ORM 本身作为独立的组件可以添加到任何的框架中,一般我都会将其添加到 Symfony,同样也可以将其添加到 CodeIgniter 。
首先新建一个全新的 CodeIgniter 项目,按照官方的操作来即可:
composer create-project codeigniter4/appstarter ciapp
然后添加 Eloquent ORM 包:
composer require illuminate/database
composer require illuminate/events
一般按照简单粗暴的方法,直接在 public 目录下的 index.php 文件内引入并且配置 Eloquent 即可,但在 CodeIgniter 却不行,因为 CodeIgniter 的 composer autoload.php 并不是在 index.php 里面引入的,因此将会找不到相关的类。
这里需要的是在框架初始化的时候,引入并且配置 Eloquent, 而且应该已较为优雅的方式而不是硬编码在框架内部。查阅文档,发现 CodeIgniter 4 加入了 event 机制,在以前的版本中应该叫 hook,实现的功能其实是差不多的,就是扩展框架核心的功能,但是 event 更加主流和强大,可以控制执行的优先级。但是 CodeIgniter 4 的 event 机制实现还是比较简单的,远没有 symfony 的 event-dispatcher 强大,而且默认系统内置的 event 也是比较少的,就 4 个,其中有一个叫:pre_system ,这个 event 会在系统初始化的时候触发,因此只要在这个 event 触发的时候初始化 Eloquent 就可以了。
查看 app/Config/Events.php 文件,里面已经有配置 pre_system 事件的方法了,我们在里面额外添加 Eloquent 初始化的方法:
<?php namespace Config;
use CodeIgniter\Events\Events;
use CodeIgniter\Exceptions\FrameworkException;
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
use Illuminate\Database\Capsule\Manager as Capsule;
function boostEloquent() {
$capsule = new Capsule;
$dbConfig = config(\Config\Eloquent::class);
$capsule->addConnection($dbConfig->default);
$capsule->setEventDispatcher(new Dispatcher(new Container));
$capsule->setAsGlobal();
$capsule->bootEloquent();
}
Events::on('pre_system', function () {
boostEloquent();
if (ENVIRONMENT !== 'testing')
{
if (ini_get('zlib.output_compression'))
{
throw FrameworkException::forEnabledZlibOutputCompression();
}
while (ob_get_level() > 0)
{
ob_end_flush();
}
ob_start(function ($buffer) {
return $buffer;
});
}
if (ENVIRONMENT !== 'production')
{
Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
Services::toolbar()->respond();
}
});
这里 dbConfig 引用的是 CodeIgniter 本身的获取配置的方法,在 app/Config 文件夹下添加 Eloquent.php 配置文件:
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Eloquent extends BaseConfig
{
public $default = [
'driver' => 'pgsql',
'host' => 'localhost',
'database' => 'poetry',
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'prefix' => '',
];
}
到此 Eloquent 就已经添加到 CodeIgniter 4 里面了,如果需要配置多个数据库,只要修改相关的配置就可以了。
最后测试一下,在 Models 文件夹下添加一个 app/Models/Poetry.php 文件:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Poetry extends Model
{
protected $table = 'poetry';
}
然后在 app/Controllers/Home.php 中修改:
<?php namespace App\Controllers;
use App\Models\Poetry;
class Home extends BaseController
{
public function index()
{
$poetry = Poetry::where('id', '>', 100)
->where('author', '李白')
->orderBy('id', 'desc')
->limit(10)
->get();
return $this->response->setJSON([
'code' => 0,
'data' => $poetry,
'msg' => 'ok',
]);
}
}
启动 CodeIgniter :
php spark serve
访问 localhost:8080 如果有对应数据输出,就表示 Eloquent 已经集成到 CodeIgniter 框架里面了,如果报错了,可以到对应的 writable/logs 查找对应的错误日志,根据错误日志进行调整。