o-log/php-model

此包最新版本(10.5)没有提供许可证信息。

带缓存的快速PHP ORM。

10.5 2019-05-10 09:35 UTC

README

通过id从数据库加载数据对象,具有多层缓存。

将对象存储到数据库中,并按id删除对象。支持更新前后的回调和自动缓存失效。

提供CLI界面用于创建模型类,同时还生成数据库迁移。

提供CLI界面用于向模型添加新字段,同时还生成数据库迁移,支持外键和选择方法生成。

代码示例

创建新模型并将其存储到数据库中

$new_model = new TestModel();
$new_model->title = rand(1, 1000);
$new_model->save();

保存后,模型将具有数据库生成的id值。

通过id从数据库加载数据模型

$model_obj = TestModel::factory(1);

模型类如下所示

class DemoModel2 implements ActiveRecordInterface
{
    use ActiveRecordTrait;

    const DB_ID = 'phpmodel';
    const DB_TABLE_NAME = 'phpmodeldemo_demomodel2';

    const _CREATED_AT_TS = 'created_at_ts';
    public $created_at_ts;
    const _ID = 'id';
    public $id;
    
    public function __construct(){
        $this->created_at_ts = time();
    }
    
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return DemoModel2[]
     */
    static public function all($limit = 30, $offset = 0){
        return self::idsToObjs(self::ids($limit, $offset));
    }

    static public function ids($limit = 30, $offset = 0){
        $ids_arr = \OLOG\DB\DB::readColumn(
            self::DB_ID,
            'select ' . self::_ID . ' from ' . self::DB_TABLE_NAME . ' order by ' . self::_CREATED_AT_TS . ' desc limit ? offset ?',
            [$limit, $offset]
        );
        return $ids_arr;
    }
}

上面是选择方法 all() 和 ids() 的类。它们返回按创建日期排序的模型和模型id数组。

选择器概念是库的重要组成部分。单独的选择器函数允许

  • 分别分析和微调每个数据库查询,这对于高负载应用程序至关重要
  • 缓存查询结果和缓存失效的单一点

当缓存列表时,仅存储ids数组到缓存中,而不是对象数组。因此,每个模型仅在模型缓存中缓存一次,并且选择缓存保持轻量。还有模型缓存的单一失效点。

贡献者安装指南

以下示例需要Linux、MacOS或具有Linux子系统的Windows,并已安装php、mysql和composer。

git clone https://github.com/o-log/php-model.git
cd php-model
composer update

现在打开Config/Config.php文件,找到以下行

DBConfig::setConnector(self::CONNECTOR_PHPMODELDEMO, new ConnectorMySQL('127.0.0.1', 'phpmodel', 'root', '1234'));

您必须将'1234'替换为您的本地mysql root用户密码。您还必须创建空的"phpmodel"数据库。

现在您已准备好执行迁移并查看演示页面

bin vendor/bin/migrate.php
bin/run

在浏览器中打开localhost:8000。

ActiveRecordTrait

特质帮助从数据库加载数据对象并保存它们。

load()方法

  • 通过id读取数据库记录并存储每个记录字段到具有相同名称的对象属性中

  • 如果给定的id未找到,则抛出异常(可以使用第二个工厂参数抑制异常)

save()方法

  • 如果对象具有非空的id值 - 使用此id值更新数据库记录。每个对象属性都存储到具有相同名称的记录字段中。

  • 如果对象的id值是空的(新对象) - 在数据库表中插入新记录。对象属性存储到记录字段中。

要使用ActiveRecordTrait类,必须

  • 有id字段

  • 有DB_TABLE_NAME常量,其值是数据库表名

  • 有DB_ID常量,其值是php-db表空间名(请参阅php-db文档)

  • 类属性必须匹配表列(尽管属性可能是受保护的)

扩展加载、保存和删除操作

您可以通过定义beforeSave()和afterSave()方法在保存模型之前和之后执行额外操作

public function beforeSave(){
    $this->setBody($this->getTitle() . $this->getTitle());
}

beforeSave()方法可以在保存之前更改模型数据或通过抛出异常阻止保存。

public function afterSave()
{
    $this->removeFromFactoryCache();

    $term_to_node_ids_arr = DemoTermToNode::idsForNodeIdByCreatedAtDesc($this->getId());
    foreach ($term_to_node_ids_arr as $term_to_node_id){
        $term_to_node_obj = DemoTermToNode::factory($term_to_node_id);
        $term_to_node_obj->setCreatedAtTs($this->getCreatedAtTs());
        $term_to_node_obj->save();
    }
}

afterSave()方法可以重置缓存或更新相关模型。

对于模型删除,可以定义相同的配对方法:canDelete()和afterDelete()

public function canDelete(&$message){
    if ($this->getDisableDelete()){
        $message = 'Delete disabled';
        return false;
    }

    return true;
}

public function afterDelete(){
    $this->removeFromFactoryCache();
    
    $match_obj = Match::factory($this->getMatchId());

    // update game title after removing teams from match
    $match_obj->regenerateTitle();
    $match_obj->save();
}

afterSave()和afterDelete()方法具有默认实现,它重置模型缓存。您必须在重写的方
建议在方法开始时重置,这样后续的任何代码都将看到对象的最新版本。

事务

保存和删除操作在事务中执行,因此您可以在beforeSave()、afterSave()、canDelete()和afterDelete()方法内部安全地抛出异常 - 数据库将恢复到保存或删除之前的状态。

创建新的模型类

要创建新的模型类,请运行vendor/bin/model并传入新的类文件路径。该工具将创建PHP类文件和数据库迁移。示例

php vendor/bin/model.php PHPModelDemo/Model.php

向模型中添加新字段

要将新字段添加到现有模型,请运行vendor/bin/model并传入现有模型文件名、新字段名和数据类型。以下示例将字符串类型的"title"字段添加到模型中

php vendor/bin/model.php PHPModelDemo/Model.php title string

工具将询问一些附加信息,然后修改模型类并生成数据库迁移。

可用数据类型

  • tinyint: SQL tinyint
  • int: SQL int
  • string: SQL varchar(255)
  • text: SQL text
  • date: SQL date
  • datetime: SQL datetime
  • bigint: SQL bigint

此外,工具还可以为新字段创建选择器方法,添加唯一键或外键。

概念

该库是在开发几个大型应用时出现的,旨在解决以下问题

  • 快速学习
  • 加快并简化应用程序的开发和支持
  • 最高性能:减少开销并简化优化

测试

运行bin/tests以执行测试。