给 CI 插上翅膀——在 CodeIgniter 2 中使用 Laravel Eloquent ORM

2014-10-22   /   阅读数:24682   /   分类: CodeIgniter

说明

本教程示例代码见 https://github.com/johnlui/CodeIgniter-2-with-Eloquent

背景介绍

CodeIgniter 框架和 Laravel 框架基本可以看做是之前若干年和这两年的 PHP 框架霸主,使用率和出镜率最高的框架。

CI 是一个轻型框架,只提供了 路由、MVC 分离、视图加载器、Active Record 等一些基本功能,但这恰恰是其使用率高的原因:提供的东西少而精,适用于绝大多数场景。CI 的文档堪称开源软件的典范,非常之清晰、详尽,对新手非常友好,十分容易上手。

Laravel 是这两年刚刚兴起的重型全功能框架,可以极大地提高开发效率,但是 Laravel 4 的文档并没有 3 那么清晰,中文资料也非常少,很多人在学习的时候遇到了比较大的困难。例如复杂的路由系统让很多用惯了 CI 自动映射的人无所适从,文档又只有寥寥几句话,导致相当一部分人被拦在了使用框架的第一步,学习的热情也被浇灭。

我前段时间写了系列教程 Laravel 4 系列入门教程【最适合中国人的Laravel教程】,访问量和反响都还不错,需要的人可以看看。

繁琐的路由让很多人怀念 CI 的自动映射,繁重的框架基础工作(一个 Hello World 页面需要载入 150 多个文件)也让 Laravel 的性能在一些场景下不能满足要求。很多人用了一段时间后发现,Laravel 中的 Eloquent ORM 是跟 CI 比最强大的地方,于是就想把 Eloquent 移植到 CI 上,我以前也想过,无奈实力不够无从下手。现在终于知道怎么搞了,下面我们正式开始。

基础准备

PHP 版本要求 >= 5.4,这是 Eloquent 的最低要求。

下载 CodeIgniter 2.2.0,地址是 http://www.codeigniter.com/download ,下载完成后解压到某个地方,配置好 HTTP 服务软件,把网站跑起来。如果你已经看到了以下画面,就可以继续往下做了:

Image

开始嫁接

我们使用 Composer 来载入和管理 Eloquent。Composer 会生成一个自动加载('autoload')文件,我们只需要 'require' 这个文件,就可以使用所有通过 Composer 安装的包。现在我们要在 CodeIgniter 项目中使用 Composer,在其根目录下新建 composer.json:

{

  "require": {

    "php": ">=5.4.0",

    "illuminate/database": "*"

  },

}

然后运行 'composer update',稍等片刻,Composer 体系创建完成,同时 illuminate/database 包也已经安装完成。

然后新建 'application/third_party/eloquent.php':

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

use Illuminate\Database\Capsule\Manager as Capsule;

// Autoload 自动载入

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

// 载入数据库配置文件

require_once APPPATH.'config/database.php';

// Eloquent ORM

$capsule = new Capsule;

$capsule->addConnection($db['eloquent']);

$capsule->bootEloquent();

这个文件将会帮我们引入 Composer 的自动加载文件,同时会帮我们初始化 Eloquent,这个文件载入了一个数据库配置文件,在 'application/config/database.php' 的最后新增(注意替换数据库名称和密码):

$db['eloquent'] = [

  'driver'    => 'mysql',

  'host'      => 'localhost',

  'database'  => 'ci',

  'username'  => 'root',

  'password'  => 'password',

  'charset'   => 'utf8',

  'collation' => 'utf8_general_ci',

  'prefix'    => ''

  ];

接下来我么需要在 CI 应用启动的时候引入上面那个文件,在最外面的 'index.php' 的后部增加:

/*

 * --------------------------------------------------------------------

 * LOAD Laravel Eloquent ORM

 * --------------------------------------------------------------------

 *

 */

require APPPATH.'third_party/eloquent.php';

注意,这段代码一定要放在 'require_once BASEPATH.'core/CodeIgniter.php';' 这一行的 前面

然后,开始使用 Eloquent,修改 'application/controllers/welcome.php' 中的 'index()' 为:

public function index()

{

  $data['article'] = Article::first();

  $this->load->view('home', $data);

}

新建 'application/views/home.php' 文件:

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <title>CI2 with Eloquent</title>

</head>

<body>

  <h1>

    <?php echo $article->title; ?>

  </h1>

  <div class="content">

    <p>

      <?php echo $article->content; ?>

    </p>

  </div>

</body>

</html>

现在让我们向数据库中填充需要使用的数据,运行 SQL 语句:

DROP TABLE IF EXISTS 'articles';

CREATE TABLE 'articles' (

  'id' int(11) unsigned NOT NULL AUTO_INCREMENT,

  'title' varchar(255) DEFAULT NULL,

  'content' longtext,

  PRIMARY KEY ('id')

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES 'articles' WRITE;

/*!40000 ALTER TABLE 'articles' DISABLE KEYS */;

INSERT INTO 'articles' ('id', 'title', 'content')

VALUES

  (1,'我是标题','<h3>我是内容呀~~</h3><p>我真的是内容,不信算了,哼~ O(∩_∩)O</p>'),

  (2,'我是标题','<h3>我是内容呀~~</h3><p>我真的是内容,不信算了,哼~ O(∩_∩)O</p>');

/*!40000 ALTER TABLE 'articles' ENABLE KEYS */;

UNLOCK TABLES;

然后建立模型,新建 'application/models/Article.php' 文件:

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

/**

* Article Model

*/

class Article extends Illuminate\Database\Eloquent\Model

{

  public $timestamps = false;

}

最后,修改 'composer.json' 将 models 文件夹加入自动加载:

{

  "require": {

    "php": ">=5.4.0",

    "illuminate/database": "*"

  },

  "autoload": {

    "classmap": [

      "application/models"

    ]

  }

}

运行 'composer dump-autoload',刷新页面!你将看到以下画面:

Image

恭喜你!Eloquent 嫁接到 CodeIgniter 2 成功!

CodeIgniter 3 正处于 DEV 阶段,原生支持 Composer,可以直接修改 composer.json 文件,配置方式和 2 完全一致。

资源汇总

1. CodeIgniter 2 with Eloquent,GitHub 地址:https://github.com/johnlui/CodeIgniter-2-with-Eloquent

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

3. Eloquent 中文文档

4. Download CodeIgniter

5. illuminate/database

WRITTEN BY

avatar

评论:

拉风的男人
2017-05-11 09:54
Eloquent orm 怎么解决事务处理呢
拉风的男人
2017-05-11 10:46
@拉风的男人:我已经解决
第一步:启动文件里加:use Illuminate\Container\Container;
然后$capsule->setAsGlobal();
如下:
$capsule = new Capsule;

$capsule->addConnection(require BASE_PATH.'/common/database.php');
$capsule->setAsGlobal();
$capsule->bootEloquent();
最后在要使用db的地方加上
use Illuminate\Database\Capsule\Manager as DB;
然后就可以用了
qwer
2016-12-20 17:27
好详细的教程啊 厉害
洋葱
2016-05-23 18:42
$capsule = new Capsule;
$capsule->addConnection($config);

关于EloquentORM嫁接到其他框架,我们公司的内部框架就是用的这个ORM,现在遇到了一个问题,如果我在执行页面的时候需要创建多个connection,如何解决?配置文件以及capsule创建的时候。。。

之前只支持一个connection,现在踩坑了让我来填坑。
我现在的方案,是使用的时候foreach循环,导致的结果是每次刷新页面都会创建新的connection,同名connection会出现很多。。。

有什么需要注意的地方被我忽略了么?请大神指点一二~
沉沦
2016-09-28 15:46
@洋葱:我也遇到相同的问题,虽然使用单例可以解决这个问题,但是我还是无法明白laravel 的依赖注入是如何解决这个的。
hh
2016-03-08 17:12
能不能把laravel 的 query builder也集成了?
Moker
2016-01-15 11:08
相关错误
Fatal error: Uncaught exception 'BadMethodCallException' with message 'Call to undefined method Illuminate\Database\Query\Builder::transaction()
Moker
2016-01-15 11:04
最近也是移植到了一个CMS当中,其他都没问题,就是通过DB::操作事务的时侯会报错 ,只要跟DB相关的方法都不能用
如果我新建一个模型  也是 无法使用事务之类
拉风的男人
2017-05-11 10:47
@Moker:能用,具体看看我在上面的回复
o0无忧亦无怖
2015-12-09 19:23
我以第三方library方式写入,但是报了一个很奇怪的错。
use Illuminate\Database\Capsule\Manager as Capsule;
class Eloquent
{
    function __construct(){
        include(APPPATH.'config/database.php');
        $config = [
            'driver'        =>  $db['default']['dbdriver'],
            'host'          =>  $db['default']['hostname'],
            'database'      =>  $db['default']['database'],
            'username'      =>  $db['default']['username'],
            'password'      =>  $db['default']['password'],
            'charset'       =>  $db['default']['char_set'],
            'collation'     =>  $db['default']['dbcollat'],
            'prefix'        =>  $db['default']['dbprefix']
        ];
        $capsule = new Capsule;
        $capsule->addConnection($config);
        $capsule->bootEloquent();
    }
}

报错信息:
Call to undefined function Illuminate\Support\value()

试过各种排错了。
shang271828
2015-07-07 11:06
多谢博主分享~
有一个问题,
如果设置$db['eloquent'] = [  'driver'    => 'mysqli' ]的话,会报这样的错误:
Unsupported driver [mysqli] in D:\wamp\www\ci_eloquent\vendor\illuminate\database\Illuminate\Database\Connectors\ConnectionFactory.php on line 194。

是不是CodeIgniter-2-with-Eloquent不支持mysqli呀?
JohnLui
2015-07-07 11:10
@shang271828:用了 Eloquent 就不要在意这些细节了,风险他都帮你解决了。
shang271828
2015-07-07 11:32
@JohnLui:恩,谢谢~
我先设置成mysql用用看
寄凡
2015-07-02 12:11
CI3.0加个Eloquent,需要依赖的东西也太多了吧,danielstjules、doctrine、mikey179、nesbot、sysfony,这些能不能优化一下?
JohnLui
2015-07-02 14:30
@寄凡:这是 Eloquent 的依赖,没法优化
snopein
2015-03-25 11:37
不能插入数据,报错
JohnLui
2015-03-25 11:59
@snopein:具体什么错?贴上来
kaka
2015-03-15 13:10
楼主好文,我正在用ci,想+Eloquent。
有个问题,怎么分页,网上搜索了一个
在Laravel外使用Eloquent(二)- 分页问题
http://overtrue.me/2014/11/25/using-eloquent-outsite-laravel-2.html
但是能力有限,不能整合到ci中,期盼大神发力,整合一下,
更新 CodeIgniter 2.2.0 with Eloquent V1.0
JohnLui
2015-03-15 15:39
@kaka:paginate 方法跟 Laravel 其他组件依赖的很深,如果还想要前端 html 输出的话,会比较麻烦。我的 TinyLara 过段时间可能会构建前端分页类,但这个工作量很大,目前还没有具体的时间规划。
天天
2015-09-06 16:49
@JohnLui:请问Eloquent如何使用分页?有相关的代码吗
黑海
2015-01-27 16:27
不错
约出一片天
2015-01-21 11:50
好吧,,搞定了。多了一个逗号……
约出一片天
2015-01-21 11:46
composer.json内容是直接复制lz的,为什么报错呢。
E:\www\CI>composer update



  [Seld\JsonLint\ParsingException]
  "./composer.json" does not contain valid JSON
  Parse error on line 9:
  ...tabase": "*"  },}
  ------------------^
  Expected: 'STRING' - It appears you have an extra trailing comma



update [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev
] [--lock] [--no-plugins] [--no-custom-installers] [--no-autoloader] [
--no-scripts] [--no-progress] [--with-dependencies] [-v|vv|vvv|--verbo
se] [-o|--optimize-autoloader] [--ignore-platform-reqs] [--prefer-stab
le] [--prefer-lowest] [packages1] ... [packagesN]
KK
2014-12-18 15:20
很强啊……
lucien
2014-10-27 15:12
什么时候整一个在CI中使用Blade 模板引擎?
JohnLui
2014-10-27 15:19
@lucien:Blade 我觉得没有太大功能上的优势,如果不依靠缓存性能还是个问题。而且使用模板引擎不适合新手学习理解 PHP 运行原理,我个人不推荐在 PHP 项目中使用模板引擎。

发表评论:

© 2011-2018 岁寒  |  Powered by Emlog