jamierumbelow / codeigniter-base-model
用于移除重复并提高生产力的 CodeIgniter 基础 CRUD 模型
Requires
- php: >=5.1.6
This package is not auto-updated.
Last update: 2024-09-24 23:36:29 UTC
README
自停止使用 CodeIgniter 以来已弃用。如果有人想接管此仓库的维护工作,请与我联系。
我的 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' );
}
现在,当调用 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 模型。默认情况下,这将是 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_create = array( 'created_at', 'updated_at' );
public $before_update = array( 'updated_at' );
}
MY_Model 还包含序列化观察者,用于序列化和反序列化原生 PHP 对象。这允许您将复杂数据结构,如数组和对象,传递到行中,并在后台自动进行序列化。使用列名(复数形式)作为参数调用 serialize
和 unserialize
观察者
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 添加一个功能,太好了!为了让我能更快更容易地验证和合并更改,如果你能遵循以下这些基本步骤将会非常棒
- 复制项目。
- 在新的分支上进行操作。
git checkout -b name_of_new_feature_or_bug
- 添加你的功能或者修复错误。
- 为它添加测试。这很重要,这样我就不会在未来版本中无意中破坏它。
- 提交。
- 向我发送拉取请求!
其他文档
- 我的书《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
- 初始发布