windwalker/record

Windwalker Record 包

安装: 13

依赖者: 0

建议者: 0

安全: 0

星标: 2

关注者: 4

分支: 0

类型:windwalker-package

3.5.23 2019-10-26 15:42 UTC

README

Windwalker Record 是一个简单的 ActiveRecord,用于操作数据库行。

通过 Composer 安装

将此添加到您的 composer.json 文件中的 require 块。

{
    "require": {
        "windwalker/record": "~3.0"
    }
}

使用 Record

创建一个实例。

use Windwalker\Record\Record;

// Record object for users table
$user = new Record('users');

或者创建一个类

use Windwalker\Record\Record;

class UserRecord extends Record
{
    protected $table = 'users';

    protected $keys = 'id';
}

$user = new UserRecord;

加载一个 Record

$user->load(25); // Load by primary key

$user->load(array('alias' => $alias)); // Load by field name.

检查行是否存在

try
{
	$record->load(25);
}
catch (NoResultException $e)
{
	// Handle error
}

绑定数据

$data = array(
    'name'     => 'Sakura',
    'username' => 'sakura',
    'alias'    => 'sakura',
    'password' => '1234',
    'desc'     => 'foo bar.'
);

$user->bind($data);

$user->name; // Sakura

如果我们有一个只有 3 列的表

绑定数据后,不在表中的字段将被移除。

$user->alias; // null

这使 Record 中的字段始终与数据库表相同。

存储

创建新行

如果主键不存在,Record 将在表中创建新行。

$data = array(
    'name'     => 'Sakura',
    'username' => 'sakura',
    'password' => '1234'
);

$user->bind($data);

$user->store();

echo $user->id; // Auto generated id

更新现有行

如果主键存在,Record 将更新它。

$data = array(
    'id'       => 30,
    'name'     => 'Sakura',
    'username' => 'sakura',
    'password' => '1234'
);

$user->bind($data);

$user->store();

验证

检查方法可以帮助您验证数据。

class UserRecord extends Record
{
    // ...

    public function validate()
    {
        if (!$this['name'])
        {
            throw new InvalidArgumentException('Name empty.');
        }

        return true;
    }
}

然后我们在调用 store() 之前调用 validate()

$user->bind($data)
    ->validate()
    ->store();

删除

$user->load(30);
$result = $user->delete(); // boolean

// OR delete by conditions

$result = $user->delete(30); // boolean
$result = $user->delete(array('username' => $username)); // boolean

Mutator 和 Accessor

Mutator 和 accessor 是设置和获取器,在通过魔术方法访问值时进行一些额外的修改。

这是一个 mutator 的示例

class ArticleRecord extends Record
{
    protected function setCreatedDateValue($value)
    {
        if ($value instanceof \DateTime)
        {
            $value = $value->format('Y-m-d H:i:s');
        }

        $this->data['created_date'] = $value;
    }
}

使用驼峰式命名方法,然后当您访问 created_date 字段时,此方法将自动执行。

$articleRecord->created_date = new \DateTime('now');

echo $articleRecord->created_date; // 2016-03-02 12:30:29

这是一个 accessor 的示例

class ArticleRecord extends Record
{
    protected function getCreatedDateValue($value)
    {
        return new \DateTime($value);
    }
}

现在您可以获取 DateTime 对象

echo $articleRecord->created_date->format('Y-m-d H:i:s'); // 2016-03-02 12:30:29

转换

添加转换以在从数据库读取后自动转换值类型

<?
class SakuraRecord extends Record
{
    protected $casts = [
        'id' => 'int',
        'price' => 'string',
        'created' => 'datetime',
        'modified' => 'timestamp',
        'images' => 'object', // or array will be json decoded
        'params' => \Windwalker\Structure\Structure::class,
        'other' => ['SomeClass', 'handle'] // Use callback
    ];
}

$sakuraRecord->load(3);

$sakuraRecord->id; // 3
$sakuraRecord->price; // '1200.00'
$sakuraRecord->created->format('Y/d/m'); // Auto convert to DateTime object
$sakuraRecord->modified; // 1497067876
$sakuraRecord->images[0]->url; // Store json in DB, can will auto decode to object.
$sakuraRecord->params->get('foo.bar'); // Use class name to store value to object

支持的转换

  • int | integer
  • real | float | double
  • string
  • bool | boolean
  • object
  • array | json
  • date | datetime
  • timestamp
  • (类名)
  • (回调数组)

NestedRecord

NestedRecord 是一个工具,帮助我们处理 嵌套集模型

创建表

名称:categories

初始化

每个嵌套集都应该有一个根节点。

$cat = new NestedRecord('categories');

$cat->createRoot();

注意:根节点 ID 为 1

创建节点

设置为根的第一个子节点

$cat->bind($data)
    ->setLocation(1, NestedRecord::LOCATION_FIRST_CHILD)
    ->store();

现在我们将有一个新的节点,其 ID 为 2。将新节点作为 2 的最后一个子节点创建。

$cat->bind($data)
    ->setLocation(2, NestedRecord::LOCATION_LAST_CHILD)
    ->store();

可用位置

  • LOCATION_FIRST_CHILD
  • LOCATION_LAST_CHILD
  • LOCATION_BEFORE
  • LOCATION_AFTER

移动节点

重新排序

$cat->move(1); // move up
$cat->move(-1); // Move down

移动到其他节点

移动到节点 3 作为最后一个子节点。

$cat->moveByReference(3, NestedRecord::LOCATION_LAST_CHILD);

重建

如果树不正确,请使用重建来重置此分支的所有 lftrgt

$cat->load(5);
$cat->rebuild(); // Rebuild node: 5 and it's children.

getPath

该方法从给定节点获取到其根的所有节点数组。

$path = $cat->getPath();

getTree

该方法获取一个节点及其所有子节点。

$records = $cat->getTree();

事件

Record 具有事件系统,我们可以在每个数据库操作之前和之后处理逻辑。

在您的 Record 类中添加事件方法。

class UserRecord extends Record
{
	public function onAfterLoad(Event $event)
	{
		$this->foo = array('a', 'b', 'c');
	}
}

或者向分发器添加监听器(您必须首先安装 windwalker/event)。

// Use listener object
$record->getDispatcher()->addListener(new MyRecordListener);

// Use callback
$record->getDispatcher()->listen('onAfterStore', function (Event $event)
{
    // Process your logic
});

可用事件

  • onBeforeLoad
  • onAfterLoad
  • onBeforeStore
  • onAfterStore
  • onBeforeDelete
  • onAfterDelete
  • onBeforeBind
  • onAfterBind
  • onBeforeCreate
  • onAfterCreate
  • onBeforeUpdate
  • onAfterUpdate