CodeIgniter、models和ORM,如何处理?

38

我刚开始学习CodeIgniter,花了几个小时在Google上深入探索后,我有点困惑。

让我们用一个简单的例子来解释我的问题:我有一个名为“car”的表,其中包含字段“name”和“color”。因此,我想要一个php类Car,这样我的代码最终可以看起来像这样:

$car = new Car('BMW', 'red'); //new $car Object
$car->save(); //this will make an SQL insert to the table 'car'

//Lets query all cars
$cars = Car::get_all(); 
//cars will be an array of Car objects, (not a set of rows!)
因此,我正在寻找类似于RubyOnRails或Django(Python)中的东西。我需要处理各种关系,并能够以真正的OOP + MVC方式编写代码。以下是我尝试过但失败的方法:
使用外部ORM(DataMapper,Doctrine,AcidCrud...),它们要求设置过多,或者在处理关系方面表现不佳。
使用CodeIgniter类(扩展CodeIgniter的Model类)。
class Car extends Model{
public function Car($name='',$color='')
{
    $this->name     =   $name;
    $this->color    =   $color;      
    parent::Model();
}
public function save()
{
    $data = array(
                   'name'   =>  $this->name ,
                   'color'  =>  $this->color 
                  );

    $this->db->insert('cars' $data);
}

然后问题来了... 这种方法的问题是,如果我对一个$car对象进行var_dump(),我会看到它包含了很多来自CodeIgniter的东西,例如CI_Config、CI_Input、CI_Benchmark等对象。因此,我认为这不是一个好的解决方案,因为每个Car类的对象都会包含大量重复的数据(性能会很差!),不是吗?

不使用CodeIgniter的模型

我可以创建我的模型而不继承CodeIgniter的Model类,然后使用常规的PHP5构造函数(__construct() 而不是 function Car()),但在这种情况下的问题是:如何访问$db对象以使用CodeIgniter的ActiveRecord进行查询? 如何在控制器中加载模型(它们的类)?


3
好问题,CodeIgniter模型在操作分层数据时需要付出很多努力。我真的很想在模型中定义和验证表单。也许结合Doctrine和表单库的一些混搭会足够。 - Benbob
1
如果你已经有Rails和Django的经验,为什么还想要使用PHP呢? - denysonique
RedBean 是一个非常易于使用的 ORM,非常棒。 - David d C e Freitas
10个回答

14

你可能想要的是这样的:

   class Cars {

    //List all neccessary vars here

    function __construct() {
        //get instance of Codeigniter Object and load database library
        $this->obj =& get_instance();
        $this->obj->load->database();
    }

//You can now list methods like so:
function selectCar($name, $color) {

        $this->obj->db->select('color')->from('car')->where('color', $color);
        $query = $this->obj->db->get();

        switch ($query->num_rows()) {
        case 0:
            return false;
            break;
        default:
            return $query->result();
            break;
        }
    }

希望这能帮到你!


请注意,这个类不属于 Codeigniter 模型 - 你应该将它放在 /system/application/libraries 中,然后使用 $this->load->library('cars') 加载它。 - Tilo Mitra
12
这根本不是ORM。基本上只是在对象内部访问数据库抽象库。 - Phillip Whelan
4
他从未明确说明需要ORM解决方案,我也没有说这是ORM。而且似乎对选择的答案进行贬低投票有点居高临下,不是吗? - Tilo Mitra
匆忙之中,我基本上锁定了帖子的实际标题,其中提到了ORM。CI的DB抽象化被称为ActiveRecord的一种实现,但在我看来,这不是正确的MVC操作方式,因为它没有类属性到列的映射,请参见:http://en.wikipedia.org/wiki/Active_record_pattern。就个人而言,在以前使用Kohana时,我很想念这个功能,特别是因为它允许您大部分时间忽略显式转义数据的需要。 - Phillip Whelan

9

尝试使用Doctrine,它是一个很棒的ORM,可以轻松集成到CodeIgniter中。


终于做到了。这个教程非常有用: http://www.phpandstuff.com/articles/codeigniter-with-doctrine-sample-code-screencast - jävi
Doctrine真的很棒,那个教程非常有用。 也请阅读以下链接(可能会有帮助):http://www.doctrine-project.org/documentation/manual/1_2/nl/caching和http://www.doctrine-project.org/documentation/manual/1_2/en/improving-performance - Daniele Teti

4

我读了这个,但更加困惑了。除了外部ORM(正如我所说,我认为它们在我的情况下不是一个好的方法),你知道这两者之间有什么区别吗: http://codeigniter.com/user_guide/database/active_record.html 和 http://codeigniter.com/wiki/ActiveRecord_Class/ - jävi

3

2

我在使用Propel和CodeIgniter时非常顺利。


请分享参考链接 - sandipshirsale

2

请查看GAS ORM,它听起来相当不错,方便易用。

以下是这个CodeIgniter ORM实现的一些特点:

  • 支持的数据库:cubrid、mssql、mysql、oci8、odbc、postgre、sqlite、sqlsrv(包括PDO,如果您与CI repo保持同步)
  • 支持多个数据库连接。
  • 支持多个关系。
  • 支持复合键(用于定义关系的键)。
  • 可以从数据库表自动创建模型,反之亦然。
  • 通过创建迁移文件自动同步模型-表。
  • 每个请求缓存。
  • 自引用和邻接列/数据(分层数据)。
  • 使用贪婪加载来最大化您的关系查询(为了性能)。
  • 各种查找器方法(可以与大多数CI AR链接)和聚合。
  • 验证和自动映射输入集合,最小设置。
  • 钩子点以控制您的模型。
  • 扩展以共享您的常见功能/库跨您的模型。
  • 事务和其他CI AR好处。
  • 包含phpunit测试套件,以确保大多数API的一致性。

还有一个支持Spark的表单 ->因此很容易安装


1

我使用CodeIgniter和Propel,它们非常兼容。我已经使用了一段时间,并且以这种方式使一些Web应用程序工作。由于我发现了一些可怕的方法(其中一些包括修改Apache的配置!!),因此我决定发布一篇博客文章来介绍如何做到这一点。你可以在这里阅读。

希望我能帮到你!


嗨,@David Conde,我看了你的帖子,你能告诉我“最好的开始方式是将Propel的运行时复制到那个文件夹中”是什么意思吗?你是指整个Propel文件夹吗?还是特定的文件夹? - pollux1er

1
你想要做的是创建一个扩展ActiveRecord类的库。有些人比你更先行一步:

http://codeigniter.com/wiki/ActiveRecord_Class/

这个帖子里有很棒的模组:

http://codeigniter.com/forums/viewthread/101987/

如果你正在寻找适用于应用程序的ORM方法,只需扩展ActiveRecord类。对于我的应用程序而言,了解表的结构允许我生成表单并进行其他映射。我进行API到API的映射,因此在MyActiveRecord中包含GetStructure()方法,并从那里构建其他东西。
(RoR嘲笑可以现在滚开了)
编辑:虽然我喜欢Doctrine的范围和功能,但我认为它对命令行使用的要求使其超出了CI的精神。适合你的就是适合你的,但如果我要使用Doctrine,我可能会选择使用Symfony,对吧?或者说,我要用RoR,对吧?看我发现了什么?正确的工具适合正确的时间。

我不同意Doctrine对于CodeIgniter来说太“笨重”的说法。“命令行使用”(它不一定要通过命令行 - 你可以轻松地将模型生成放在CI控制器内并从Web中调用)只是为了生成模型定义,这大大减少了你需要在CodeIgniter内处理模型的工作量。在我看来,CI的精神完全是关于快速开发速度的,而Doctrine在这方面帮助非常大。 - Alex Dean

0

我认为php-activerecord是一个非常好的drop-in ORM。我已经在Slim Framework中使用过它几次,我认为它将成为使用CI的本地模型类的一个很好的替代品。这里有一些示例代码和链接:

$post = new Post();
$post->title = 'My first blog post!!';
$post->author_id = 5;
$post->save();

PHP ActiveRecord

{{链接1:PHP ActiveRecord}}


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接