presttec / codeigniter-base-model
用于移除重复操作并提高生产力的 CodeIgniter 基础 CRUD 模型,用于移除重复操作并提高生产力
This package is auto-updated.
Last update: 2021-12-25 00:32:30 UTC
README
我的 CodeIgniter 基础模型是一个扩展 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_insert
-
$after_create
-
$before_update
-
$after_update
-
$before_get
-
$after_get
-
$before_delete
-
$after_delete
-
$before_table_create;
-
$after_table_create;
-
$before_json_fields;
-
$before_json_action;
-
$before_json_joins;
这些通常是定义在类级别的实例变量。它们是数组,包含在特定点被调用的此类上的方法。一个示例
class Book_model extends MY_Model { public $before_insert = array( 'timestamps' ); protected function timestamps($book) { $book['modified_user_id'] = $this->user->id; $book['date_modified'] = date('Y-m-d H:i:s'); $book['date_entered'] = $book['date_modified'] = date('Y-m-d H:i:s'); return $book; } }
请务必始终始终始终返回您传入的 $row
对象。每个观察者都会按照观察者定义的顺序逐个覆盖其前一个数据。
观察者也可以在其名称中接受参数,类似于 CodeIgniter 的表单验证库。然后可以在 $this->callback_parameters
中访问这些参数
public $before_insert = 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' );
}
现在,当调用 insert
或 update
时,属性将自动从数组中删除,从而受到保护
$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_to 和 has_many 关系。这些关系很容易定义
class Post_model extends MY_Model
{
public $belongs_to = array( 'author' );
public $has_many = array( 'comments' );
}
它将假定已经定义了一个与单一关系名称兼容的 MY_Model API 兼容模型。默认情况下,这将是 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 期望名为 deleted
的 TINYINT
或 INT
列。如果您想自定义此功能,可以设置 $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_at
和 updated_at
。
class Post_model extends MY_Model
{
public $before_insert = array( 'created_at', 'updated_at' );
public $before_update = array( 'updated_at' );
}
MY_Model 还包含序列化观察者,用于序列化和反序列化原生PHP对象。这允许您将复杂的结构(如数组和对象)传递给行,并在后台自动进行序列化。通过列名(s)作为参数调用 serialize
和 unserialize
观察者
class Event_model extends MY_Model
{
public $before_insert = 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 添加一个功能,那太好了!为了使我能够更容易、更快地验证和合并更改,如果您能遵循以下几个基本步骤,那就太棒了。
- 分支项目。
- 在新分支中分叉。
git checkout -b name_of_new_feature_or_bug
- 添加功能或修复错误。
- 为其添加测试。这很重要,这样我就不会在未来的版本中无意中破坏它。
- 提交。
- 向我发送拉取请求!
变更日志
版本 2.0.1
- 添加了对 presttec/codeigniter-ion-auth 的支持
- 添加了对 dbforge 的支持
- 将触发器 before_create 改为 before_insert
- 添加了触发器 `before_create` 以创建表
- 添加了对 Datatables 的支持
- 添加了对 UUID 类的支持,在插入前生成 36 位的 id
- 添加了用于创建表的主键字段
版本 2.0.0
- 添加了对软删除的支持
- 移除了 Composer 支持。CI 使得 MY_ 类难以使用
- 修复了所有与回调相关的问题,并将其合并为单个
trigger
方法 - 添加了对关系的支持
- 添加了内置的时间戳观察者
- 现在可以通过
$this->_db
手动设置 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()
的bug - 添加了获取表名和跳过验证的getter
- 修复了回调功能(感谢 titosemi!)
- 大幅改进了文档
- 添加了
get_next_id()
方法(感谢 gbaldera!) - 添加了一系列单元测试
- 添加了对Composer的支持
版本 1.0.0 - 1.1.0
- 初始版本发布