barcodex/kasha-model

为 Kasha PHP 框架提供 DB 模型支持

dev-master 2015-04-19 20:49 UTC

This package is not auto-updated.

Last update: 2024-09-28 17:54:27 UTC


README

模型库旨在用于基于 Kasha 框架构建的 Web 应用程序。

它是一个简单的数据库抽象层,不是为了与 ORM 库竞争。

然而,它极大地简化了使用业务对象(这些对象是扩展 Kasha\Model\Model 的类的实例)与数据库表一起工作。

安装

使用 Composer 安装模型库,通过将要求添加到项目的 composer.json 中

{
   "require": {
        "barcodex/kasha-model": "*"
   }
}

或从命令行要求它

composer require barcodex/kasha-model:*

## API

此基类(Kasha\Model\Model)包含大量通用代码,适用于任何数据库表包装器,例如 CRUD 操作、反射、字符串字段的国际化以及后处理触发器的占位符。

公共方法(不完整列表)

还有一些用于在扩展 Kasha\Model\Model 的业务类中非常有用的方法的占位符

## 约定

Kasha 假设数据库表结构遵循某些规则

  • 表中至少有一个 'id' 字段。即使表是映射表,也始终添加 'id' 字段
  • 有一个名为 'created' 的字段来标记创建此行的时间
  • 有名为 'updated' 和 'editor' 的字段来标记最后更新时间和进行此编辑的用户 ID

内部

Kasha 整个框架都青睐 PHP 的标准关联数组 - 如果你曾经尝试在 mysql 结果上使用 fetch_assoc 方法,你就知道这样一个数组如何表示表中的一行。

模型子类建立在内部称为 'data' 的数组之上。要从任何时刻获取此数组,只需调用 getData() 方法。

当然,模型是一个业务对象,这意味着可以在数据数组之上构建任何逻辑 - 最值得注意的是添加新字段。

然而,我们强烈建议在 getExtendedData() 方法(默认情况下仅包装 getData())内扩展原始数据数组。

$bookModel = new Book();
// use load() to populate model object with data, it's chainable
$data = $book->load($id)->getData(); // data that corresponds to table structure
$extendedData = $book->getExtendedData(); // same data plus additional fields

使用模型子类的一个最大优点实际上是后处理钩子功能。你可以在 onDelete()、onInsert() 和 onUpdate() 方法中实现你的业务逻辑(级联删除/更新、刷新统计数据、清除缓存值、排队消息、发送邮件等 - 你可以命名它),并且你可以根据更改的字段或甚至这些字段的前期值来做这件事。

例如,你可以编写特定的代码,仅在字段 'status' 从 'open' 更改为 'progress' 或当 'views' 列的值超过 100 时触发。在这里,我们将更新书籍被添加到关注列表时关注的计数器

class WatchList extends Model {
	public function onInsert($id) {
		$bookId = $this->get('book');
		$bookModel = new Book();
		$bookModel->load($bookId);
		$cnt = $bookModel->get('cnt_watched');
		$bookModel->update(array('cnt_watched' => $cnt+1));
	}
}

对于对字段进行简单更新,只需将包含更改字段的关联数组传递给 update() 方法

$user = new User();
$user->load(3); // loads $user object with data fetched by given id=3
$user->update(array('first_name' => 'John', 'last_name' => 'Doe'));

## 缓存

为 Kasha 的模型库也支持缓存。

类 Kasha\Model\Cache 扩展了标准的 Kasha\Caching\Cache,包含一些处理模型数据和元数据的便捷方法。

作为库的消费者,你甚至不需要了解与缓存相关的类的内部结构,但你需要知道缓存的值存储在哪里。

目前,唯一支持的缓存存储是文件系统,因此与模型相关的缓存值存储在与Kasha框架中其他所有内容相同的/app/cache文件夹下。模型组件将确保表的元数据(文件名为[tableName].txt)存储在/app/cache/metadata下,并且与表行相对应的json对象(根据扩展Kasha\Model\Model的业务对象逻辑,可能包含更多计算数据)存储在/app/cache/data中,然后按表的名称排序存储在名为[id].txt的文件中。

例如,如果为Model库启用了缓存,并且脚本正在处理id=84的国家,那么脚本运行后,/app/cache文件夹中会出现一些新文件。

/app
 /cache
  /metadata
   /country.txt
  /models
   /country
    /84.txt

理论上,每个模型对象甚至可以有自己的缓存——可以使用setCache()方法设置——唯一的要求是提供的对象扩展了Model\Caching\Cache基类。

然而,在大多数情况下,使用标准的Kasha\Model\Cache就足够了——为此,您不需要明确指定任何内容。使用标准模式的一个小问题是,每个模型的构造方法都尝试通过Kasha\Model\ModelConfig类设置接收到的缓存对象。这个类反过来使用与标准Kasha\Caching\Cache相同的根文件夹路径实例化Kasha\Model\Cache,这意味着它应该在任何模型使用之前实例化。

以下是一个示例脚本来说明这一点(我们假设它在应用程序的根目录中运行)

$cache = new Cache(__DIR__ . '/app/cache/');

$country = new Country();
$list = $country->getList(array('iso2' => 'AZ'));

这段代码的第一行确保为脚本中的任何后续代码(包括其自己的子类)使用实例化了基础缓存类。

Country类的构造方法要求Kasha\Model\ModelConfig提供一个缓存实例,默认情况下将是一个Kasha\Model\Cache实例,与Kasha\Caching\Cache在相同的根文件夹中创建,在代码片段的第一行实例化。

如果需要,也可以通过提供另一个Cache类来覆盖默认行为