swiekenb/dirty

一个库,用于检查对象或数组自上次检查以来是否有变化(是否已脏)。

v0.0.1 2024-07-14 11:51 UTC

This package is auto-updated.

Last update: 2024-09-14 13:20:30 UTC


README

一个库,用于检查对象或数组自上次检查以来是否有变化(是否已脏)。

许可证:MIT

安装

composer require sweikenb/dirty

如果您计划在一个 Symfony 项目中使用此库,请考虑检查相应的 DirtyBundle

用法

它是如何工作的?

为了检查测试对象是否有未跟踪的变化,将使用可配置的存储适配器对给定的对象或数组进行标准化、展平和存储。

下一次执行检查时,将比较当前数据与上次检查的数据。哪些字段将被跟踪或忽略可以配置(见下文)。

用法

检查结果将提供一个详细字段更改列表及其相应的先前和当前值。

$categoryId = 'category:123';
$categoryData = [
    'title' => 'My Category', 
    'tags' => ['Foo', 'Bar', 'Baz'],
    'createdAt' => '2024-07-10 15:31:00' 
];

$service = new \Sweikenb\Library\Dirty\Service\DirtyCheckService();

$result = $service->execute($categoryId, $categoryData);

if ($result->isDirty) {
    foreach ($result->diffs as $fieldPath => $diff) {
        echo sprintf("Field '%s' is dirty! '%s' -> '%s'\n", $fieldPath, $diff->previously, $diff->currently);
    }
}

配置

在某些情况下,您可能有一些包含易变值(例如动态时间戳)的数据结构,这些值将始终触发脏检查的假阳性。

忽略字段

如果您想忽略某些字段,可以指定在检查期间应忽略哪些字段。如果配置的字段包含复杂数据(对象或数组),则受影响的字段及其后续所有数据将被忽略(该字段充当通配符)。

$userId = 'user:123';
$userData = [
    'username' => 'some-user' 
    'security' => [
        'password' => '...',
        'passwordSalt' => '...',
        'pgp-key' => '...'
    ]
    'meta' => [
        'source' => 'sso'
        'createdAt' => '2024-07-10 15:41:10'
    ]
];

$config = new \Sweikenb\Library\Dirty\Model\ConfigModel(ignoreFieldPath: [
    'security',         // will ignore the whole "security" subset 
    'meta.createdAt'    // will only ignore the "createdAt" field under "meta"
]);

$service = new \Sweikenb\Library\Dirty\Service\DirtyCheckService();

$result = $service->execute($userId, $userData, $config);

if ($result->isDirty) {
    foreach ($result->diffs as $fieldPath => $diff) {
        echo sprintf("Field '%s' is dirty! '%s' -> '%s'\n", $fieldPath, $diff->previously, $diff->currently);
    }
}

仅检查特定字段

您还可以显式允许应检查的字段,其他任何字段都将被忽略。如果配置的字段包含复杂数据(对象或数组),则受影响的字段及其后续所有数据将被检查(该字段充当通配符)。

$userId = 'user:123';
$userData = [
    'username' => 'some-user' 
    'security' => [
        'password' => '...',
        'passwordSalt' => '...',
        'pgp-key' => '...',
    ]
    'meta' => [
        'source' => 'sso'
        'createdAt' => '2024-07-10 15:41:10'
    ]
];

$config = new \Sweikenb\Library\Dirty\Model\ConfigModel([
    'username',     // check the "username" field
    'meta',         // check the "meta" field with all containing sub-fields
]);

$service = new \Sweikenb\Library\Dirty\Service\DirtyCheckService();

$result = $service->execute($userId, $userData, $config);

if ($result->isDirty) {
    foreach ($result->diffs as $fieldPath => $diff) {
        echo sprintf("Field '%s' is dirty! '%s' -> '%s'\n", $fieldPath, $diff->previously, $diff->currently);
    }
}

组合检查和忽略字段

请注意,"忽略"配置将在"允许"配置之后应用,这意味着您可以组合它们以启用某些结构,然后显式地从其中删除单个字段或其子集。

$userId = 'user:123';
$userData = [
    'username' => 'some-user' 
    'security' => [
        'password' => '...',
        'passwordSalt' => '...',
        'pgp-key' => '...',
    ]
    'meta' => [
        'source' => 'sso'
        'createdAt' => '2024-07-10 15:41:10'
    ]
];

$config = new \Sweikenb\Library\Dirty\Model\ConfigModel(
    [
        'username',        // check the "username" field
        'meta',            // check the "meta" field with all containing sub-fields
    ],
    [
        'meta.createdAt',  // ignore the "createdAt" sub-field even tough "meta" was explicitly configured to be checked
    ]
);

$service = new \Sweikenb\Library\Dirty\Service\DirtyCheckService();

$result = $service->execute($userId, $userData, $config);

if ($result->isDirty) {
    foreach ($result->diffs as $fieldPath => $diff) {
        echo sprintf("Field '%s' is dirty! '%s' -> '%s'\n", $fieldPath, $diff->previously, $diff->currently);
    }
}

存储适配器

存储适配器及其主要用例

  • 文件系统适配器 (默认)
    • 本地 开发 或阶段环境
    • 单服务器设置
    • 要检查的数据量很少
    • 此适配器**不推荐**与网络存储挂载一起使用,并且高度受益于快速的底层存储(例如SSD)。
    • 文件将不会自动清理,您需要编写自己的脚本进行清理!
  • REDIS 适配器 (或兼容的,如"ValKey")
    • Symfony 应用程序通过 DirtyBundle
    • 生产 或阶段环境
    • 多服务器设置
    • 任何数据集大小

如果需要,您可以通过实现 Sweikenb\Library\Dirty\Api\StorageAdapterInterface 来添加自定义存储适配器。

配置和自定义

  • 待办事项