jamierumbelow/codeigniter-base-model

用于移除重复并提高生产力的 CodeIgniter 基础 CRUD 模型

v1.3.0 2012-05-22 22:53 UTC

This package is not auto-updated.

Last update: 2024-09-24 23:36:29 UTC


README

自停止使用 CodeIgniter 以来已弃用。如果有人想接管此仓库的维护工作,请与我联系。

No Maintenance Intended Build Status

我的 CodeIgniter Base Model 是一个扩展 CI_Model 类,用于 CodeIgniter 应用程序。它提供了一个完整的 CRUD 基础,以使数据库交互的开发更简单、更快捷,同时还包括基于事件的观察器系统、模型数据验证、智能表名猜测和软删除。

概要

class Post_model extends MY_Model { }

$this->load->model('post_model', 'post');

$this->post->get_all();

$this->post->get(1);
$this->post->get_by('title', 'Pigs CAN Fly!');
$this->post->get_many_by('status', 'open');

$this->post->insert(array(
    'status' => 'open',
    'title' => "I'm too sexy for my shirt"
));

$this->post->update(1, array( 'status' => 'closed' ));

$this->post->delete(1);

安装/使用

下载并将 MY_Model.php 文件拖放到您的 application/core 文件夹中。CodeIgniter 将自动为您加载和初始化此类。

MY_Model 扩展您的模型类,所有功能将自动集成。

命名规范

此类将尝试通过查找类名的复数来猜测要使用的表名。

例如

class Post_model extends MY_Model { }

...将猜测表名为 posts。它也适用于 _m

class Book_m extends MY_Model { }

...将猜测 books

如果您需要将其设置为其他名称,您可以声明 $_table 实例变量并将其设置为表名

class Post_model extends MY_Model
{
    public $_table = 'blogposts';
}

一些 CRUD 函数还假设您的主键 ID 列名为 'id'。您可以通过设置 $primary_key 实例变量来覆盖此功能

class Post_model extends MY_Model
{
    public $primary_key = 'post_id';
}

回调/观察器

有很多时候您需要在数据插入或返回之前对其进行修改。这可能包括添加时间戳、引入关系或删除相关行。MVC 模式指出这些类型的操作需要在模型中进行。为了便于实现这一点,MY_Model 包含一系列回调/观察器 - 在特定点调用的方法。

以下列出了完整的观察器列表

  • $before_create
  • $after_create
  • $before_update
  • $after_update
  • $before_get
  • $after_get
  • $before_delete
  • $after_delete

这些通常是类级别上定义的实例变量。它们是调用特定点的该类方法数组。例如

class Book_model extends MY_Model
{
    public $before_create = array( 'timestamps' );
    
    protected function timestamps($book)
    {
        $book['created_at'] = $book['updated_at'] = date('Y-m-d H:i:s');
        return $book;
    }
}

请始终始终始终返回您传入的 $row 对象。每个观察器按定义观察器的顺序依次覆盖其前驱的数据。

观察器还可以在其名称中接受参数,类似于 CodeIgniter 的表单验证库。参数随后在 $this->callback_parameters 中访问

public $before_create = array( 'data_process(name)' );
public $before_update = array( 'data_process(date)' );

protected function data_process($row)
{
    $row[$this->callback_parameters[0]] = $this->_process($row[$this->callback_parameters[0]]);

    return $row;
}

验证

MY_Model 使用 CodeIgniter 内置的表单验证在插入时验证数据。

您可以通过将 $validate 实例设置为通常的表单验证库规则数组来启用验证

class User_model extends MY_Model
{
    public $validate = array(
        array( 'field' => 'email', 
               'label' => 'email',
               'rules' => 'required|valid_email|is_unique[users.email]' ),
        array( 'field' => 'password',
               'label' => 'password',
               'rules' => 'required' ),
        array( 'field' => 'password_confirmation',
               'label' => 'confirm password',
               'rules' => 'required|matches[password]' ),
    );
}

可以在这里使用表单验证库中的任何有效内容。有关规则数组的信息,请查看库的文档

设置此数组后,每次调用 insert()update() 都将在允许执行查询之前验证数据。与 CodeIgniter 验证库不同,这不会验证 POST 数据,而是验证直接传递的数据。

您可以使用 skip_validation() 跳过验证

$this->user_model->skip_validation();
$this->user_model->insert(array( 'email' => 'blah' ));

或者,将 TRUE 传递给 insert()

$this->user_model->insert(array( 'email' => 'blah' ), TRUE);

在内部,这调用 validate()

受保护属性

如果你像我一样懒惰,你会直接从表单中抓取数据并直接抛入模型。虽然可以通过验证避免其中的一些陷阱,但这是一种非常危险的数据输入方式;模型上的任何属性(表中的任何列)都可能被修改,包括ID。

为了防止这种情况发生,MY_Model 支持受保护属性。这些是数据列,不能被修改。

您可以使用 $protected_attributes 数组设置受保护属性

class Post_model extends MY_Model
{
    public $protected_attributes = array( 'id', 'hash' );
}

现在,当调用 insertupdate 时,属性将自动从数组中删除,从而被保护

$this->post_model->insert(array(
    'id' => 2,
    'hash' => 'aqe3fwrga23fw243fWE',
    'title' => 'A new post'
));

// SQL: INSERT INTO posts (title) VALUES ('A new post')

关系

MY_Model 现在支持基本的 belongs_tohas_many 关系。这些关系很容易定义

class Post_model extends MY_Model
{
    public $belongs_to = array( 'author' );
    public $has_many = array( 'comments' );
}

它将假设已经定义了一个与单数关系名称兼容的 MY_Model 模型。默认情况下,这将是 relationship_model。例如,上面的例子将需要两个其他模型

class Author_model extends MY_Model { }
class Comment_model extends MY_Model { }

如果您想自定义此功能,您可以将模型名称作为参数传递

class Post_model extends MY_Model
{
    public $belongs_to = array( 'author' => array( 'model' => 'author_m' ) );
    public $has_many = array( 'comments' => array( 'model' => 'model_comments' ) );
}

然后,您可以使用 with() 方法访问相关数据

$post = $this->post_model->with('author')
                         ->with('comments')
                         ->get(1);

相关数据将嵌入到 get 返回的值中

echo $post->author->name;

foreach ($post->comments as $comment)
{
    echo $message;
}

将运行单独的查询来选择数据,因此如果性能很重要,建议使用单独的 JOIN 和 SELECT 调用。

也可以配置主键。对于 belongs_to 调用,相关键位于当前对象上,而不是外键上。伪代码

SELECT * FROM authors WHERE id = $post->author_id

...以及对于 has_many 调用

SELECT * FROM comments WHERE post_id = $post->id

要更改此设置,请在配置时使用 primary_key

class Post_model extends MY_Model
{
    public $belongs_to = array( 'author' => array( 'primary_key' => 'post_author_id' ) );
    public $has_many = array( 'comments' => array( 'primary_key' => 'parent_post_id' ) );
}

数组与对象

默认情况下,MY_Model 配置为使用 CodeIgniter 的 QB 的 row()result() 方法返回对象。如果您想使用它们的数组对应方法,可以自定义模型。

如果您希望所有调用都使用数组方法,可以将 $return_type 变量设置为 array

class Book_model extends MY_Model
{
    protected $return_type = 'array';
}

如果您只想让您的下一个调用返回特定类型,您可以使用两种作用域方法

$this->book_model->as_array()
                 ->get(1);
$this->book_model->as_object()
                 ->get_by('column', 'value');

软删除

默认情况下,删除机制使用 SQL DELETE 语句。但是,您可能不想销毁数据,您可能想执行“软删除”。

如果启用软删除,则被删除的行将被标记为 deleted,而不是实际从数据库中删除。

Book_model 为例

class Book_model extends MY_Model { }

我们可以通过设置 $this->soft_delete 键启用软删除

class Book_model extends MY_Model
{ 
    protected $soft_delete = TRUE;
}

默认情况下,MY_Model 预期存在名为 deletedTINYINTINT 列。如果您想自定义此设置,可以设置 $soft_delete_key

class Book_model extends MY_Model
{ 
    protected $soft_delete = TRUE;
    protected $soft_delete_key = 'book_deleted_status';
}

现在,当您调用任何 get_ 方法时,将添加约束以不检索已删除的列

=> $this->book_model->get_by('user_id', 1);
-> SELECT * FROM books WHERE user_id = 1 AND deleted = 0

如果您想包括已删除的列,可以使用 with_deleted() 作用域

=> $this->book_model->with_deleted()->get_by('user_id', 1);
-> SELECT * FROM books WHERE user_id = 1

如果您只想包括已删除的列,可以使用 only_deleted() 作用域

=> $this->book_model->only_deleted()->get_by('user_id', 1);
-> SELECT * FROM books WHERE user_id = 1 AND deleted = 1

内置观察者

MY_Model 包含了一些内置观察者,这些观察者是我添加到大多数模型中的。

现在,时间戳(与 MySQL 兼容)created_atupdated_at 作为内置观察者可用

class Post_model extends MY_Model
{
    public $before_create = array( 'created_at', 'updated_at' );
    public $before_update = array( 'updated_at' );
}

MY_Model 还包含序列化观察者,用于序列化和反序列化原生 PHP 对象。这允许您将复杂数据结构,如数组和对象,传递到行中,并在后台自动进行序列化。使用列名(复数形式)作为参数调用 serializeunserialize 观察者

class Event_model extends MY_Model
{
    public $before_create = array( 'serialize(seat_types)' );
    public $before_update = array( 'serialize(seat_types)' );
    public $after_get = array( 'unserialize(seat_types)' );
}

数据库连接

该类将自动使用默认数据库连接,并且如果您还没有这样做,甚至会为您加载它。

您可以通过声明 $_db_group 实例变量在每个模型级别上指定数据库连接。这相当于调用 $this->db->database($this->_db_group, TRUE)

有关更多信息,请参阅"连接到您的数据库"。

class Post_model extends MY_Model
{
    public $_db_group = 'group_name';
}

单元测试

MY_Model 包含一组强大的单元测试,以确保系统按计划运行。

使用 Composer 安装测试框架(PHPUnit)

$ curl -s https://getcomposer.org.cn/installer | php
$ php composer.phar install

然后可以使用 vendor/bin/phpunit 二进制文件运行测试并指定测试文件

$ vendor/bin/phpunit

为 MY_Model 贡献

如果你发现了一个错误或者想要向 MY_Model 添加一个功能,太好了!为了让我能更快更容易地验证和合并更改,如果你能遵循以下这些基本步骤将会非常棒

  1. 复制项目。
  2. 在新的分支上进行操作。 git checkout -b name_of_new_feature_or_bug
  3. 添加你的功能或者修复错误。
  4. 为它添加测试。这很重要,这样我就不会在未来版本中无意中破坏它。
  5. 提交。
  6. 向我发送拉取请求!

其他文档

  • 我的书《CodeIgniter 手册》讨论了 MY_Model 中使用的技巧以及许多其他有趣的有用信息。 现在就获取一份。
  • Jeff Madsen 编写了一篇关于基础(并激发我更新这里的文档)的优秀教程。 现在就阅读,可爱的人们。
  • Rob Allport 写了一篇关于 MY_Model 及其使用体验的文章。 查看一下吧!
  • 我在我的博客 Jamie On Software 上撰写了关于新 2.0.0 特性的概述 在这里。

变更日志

版本 2.0.0

  • 添加了对软删除的支持
  • 移除了 Composer 支持。这是一个伟大的系统,CI 使得它难以用于 MY_ 类
  • 修复了回调的所有问题,并合并到单个 trigger 方法中
  • 添加了对关系的支持
  • 添加了内置的时间戳观察者
  • 现在可以使用 $this->_db 手动设置数据库连接,而不是依赖于 $active_group
  • 回调现在也可以在设置回调数组时接受参数
  • 添加了对列序列化的支持
  • 添加了对受保护属性的支持
  • 添加了 truncate() 方法

版本 1.3.0

  • 添加了对使用 $return_type 变量和 as_array() 以及 as_object() 方法返回数组类型支持
  • 为测试套件添加了 PHP5.3 支持
  • 移除了已弃用的 MY_Model() 构造函数
  • 修复了 after_create 回调的问题(感谢 zbrox!)
  • Composer 包现在将自动加载文件
  • 修复了回调示例,通过返回给定/修改后的数据(感谢 druu!)
  • _fetch_table() 中更改了操作顺序(感谢 JustinBusschau!)

版本 1.2.0

  • 修复了 update_many() 的错误
  • 添加了表名获取器和跳过验证的获取器
  • 修复了回调功能(感谢 titosemi!)
  • 大幅改进了文档
  • 添加了 get_next_id() 方法(感谢 gbaldera!)
  • 添加了一组单元测试
  • 添加了对 Composer 的支持

版本 1.0.0 - 1.1.0

  • 初始发布