扩展CodeIgniter模型的类设计问题

时间:2013-06-28 09:39:10

标签: php codeigniter design-patterns model abstraction

这个问题非常具体而且很长,并涉及扩展CodeIgniter的模型。这并不重要(我的申请目前正在运作),但我问这个是因为我想知道是否有一种“干净”的方式来做这件事。

我经常写一篇blog post关于我正在使用的技巧为我的模型制作CRUD方法通用。因为我只涉及模型时使用“数据库”库,所以我扩展了核心模型(MY_Model),只是从构造函数中加载数据库而不是自动加载它。自动加载它并不是什么大不了的事,但关键是(并且对于后面的内容很重要);我可能希望将来使用此构造函数执行其他操作,因此需要作为构造函数。

当我尝试将CRUD方法设为通用时,我想到了再次使用MY_Model,并且能够成功定义“create”,“update”,“delete”和“load_from_id”方法。但是,这些方法隐含地依赖于接口,或者需要在任何模型中定义的方法集(除了静态/常量参数覆盖,例如一些验证,或者函数是调用delete来级联DB中的特定结果)。两种解决方案使用PHP 接口或使MY_Model 抽象并声明抽象方法。

解决方案2无法实现,因为我需要在MY_Model中有一个有效的构造函数,并且在任何情况下,我都需要能够调用CI_Model的构造函数(即使到目前为止还没有任何内容,我不能假设从来没有将会)。在这种情况下,继承栈将是(具体[CI_Model],抽象[MY_Model],具体[Any_model]),我需要在调用时“跳过一代”来自我的具体模型的parent::__construct();。另外,我不知道CI是否支持抽象核心类扩展。

对于解决方案1,我不确定它是否也可以实现。假设我定义了一个具体的类MY_Model和一个接口CrudModelInterface。我将所有属性放在MY_Model中(它们不能在界面中),但是我的CRUD方法需要使用它们,因此CrudModelInterface必须扩展MY_Model吗?这就是我对它模糊的地方......

如果你明白我想做什么,你能告诉我关于我的设计,你将如何做,等等。任何建设性的东西。目前,我根本没有强加约束来定义那些“接口方法”,但我在每个模型中都这样做,所以它可以工作。它不是很干净。

1 个答案:

答案 0 :(得分:1)

推荐选项是使用增压DataMapper ORM for CodeIgniter或其他ORM库,而不是编写自己的东西。

但是在回答您的直接问题时,我认为您并不需要界面或抽象功能。这是MY_Model和另一个具体模型的快速示例

class MY_Model extends CI_Model {

   public $_table;

   public function find_all() {
        return $this->db->from($this->_table)->get()->result_object();
   }

   public function find_by_id($id, $id_field_name = 'id') {
        $this->db->where("$this->_table.$id_field_name", $id);
        $result = $this->find_all();
        return count($result) == 1 ? $result[0] : null;
   }

   public function insert($data) {
        $this->db->insert($this->_table, (array) $data);
        $id = $this->db->insert_id();
        return $id;
   }

   public function update($id, $data) {
        if ($id != null) {  // update existing record
            $updated = $this->db->update($this->_table, $data, "id = $id");
            return $updated;
        } else {            // add a new record
            $inserted = $this->insert($data);
            return $inserted;
        }
   }

   public function delete($id) {
        $deleted = $this->db->delete($this->_table, array('id' => $id), 1);
        return $deleted;
   }

    .........

}

现在你要做的就是获取MY_Model函数的利润是定义你的模型并用表名设置$ _table变量。

class Users_Model extends MY_Model {

    public $_table = 'users';

}

显然你可以在MY_Model中添加很多其他方法来进一步扩展它。这种方法来自Bonfire,它是建立在CodeIgniter之上的HMVC。 See their implementation of MY_Model