dashifen/repository

一个具有只读受保护属性的对象,其他对象可以从该对象扩展。

4.0.0 2023-09-05 17:51 UTC

README

仓库(名词):一个地方、建筑物或容器,用于存放或可能存放物品。

此包定义了一个对象 AbstractRepository,它通过使用 __get() 提供对其受保护属性的只读访问。如果需要保持某些受保护属性对外部作用域隐藏,您可以指定一个列表,该列表将以这种方式返回。

安装

composer install dashifen/repository

使用

这里有两种方法

  1. 扩展 AbstractRepository 对象。
  2. 扩展 Repository 对象。

如果您扩展抽象对象,您将被迫实现三个方法

  1. getHiddenPropertyNames - 返回一个数组,其中包含应通过箭头操作符保持不可访问的属性,
  2. getCustomPropertyDefaults - 设置比属性声明期间可以设置的更复杂的默认值,
  3. getRequiredProperties - 返回一个列表,其中包含对象实例化后必须具有值的属性。

Repository 对象已经实现了这些方法;它们各自返回空数组。

构造函数

Repository 的构造函数接受一个关联数组的数据,其中索引是属性的名称,数组值将设置为列表属性的值。如果您编写一个设置器,它将使用值进行验证而被调用。

构造函数的数组参数的索引可以是对象的属性的预期驼峰式名称,也可以是HTML属性中的短横线分隔式名称。因此,索引 start-date 将与 startDate 属性“相关联”。

获取器

通常,由于仓库公开受保护属性,使用箭头操作符获取它们是首选的方法。但是,如果您想对外部作用域转换属性的内部表示,您可以定义一个执行转换并返回结果的属性获取器。例如,将日期从 YYYY-MM-DD 格式转换为 MM/DD/YYYY 以在屏幕上显示。

获取器必须采用 "get" . ucfirst($propertyName) 的形式。因此,startDate 属性将有一个获取器 getStartDate()。如果需要隐藏它们以供外部作用域使用,并且依赖于 __get() 实现和箭头操作符进行访问,则获取器可以是受保护的。

设置器

仓库不实现 __set(),因此您必须自己编写它们。默认情况下,AbstractRepository 对象将使用其 __construct() 方法中的设置器。因此,如果您扩展该对象,您必须为预期由该构造函数使用的每个属性创建一个设置器,即由构造函数的数组参数引用的属性。

与获取器一样,它们必须采用 "set" . ucfirst($propertyName) 的格式。因此,startDate 的设置器必须是 setStartDate()。如果您实现设置器,它们将在仓库构造函数迭代其数组参数时被调用。因为它们是从构造函数中调用的,所以它们可以是受保护的或私有的,以在构造后创建具有只读属性的实例。

示例

class Foo extends AbstractRepository {
    protected $bar;
    protected $baz;
    protected $bing;
    
    protected function getHiddenPropertyNames(): array 
    {
        return ["baz"];
    }
    
    protected function getCustomPropertyDefaults(): array 
    {
        return ["bing" => strtotime('Y-m-d h:i:s')];
    }
    
    protected function getRequiredProperties(): array 
    {
        return ["bar"];
    }

    protected function setBar(string $bar): void 
    {
        $this->bar = $bar;   
    }
    
    protected function getBar(): string 
    {
        return ucfirst($this->bar);
    }
}

$foo = new Foo(["bar" => "apple"]);

echo $foo->bar;         // echos "Apple" because of the getBar() getter
echo $foo->baz;         // throws RepositoryException (baz is hidden)
echo $foo->bing;        // echos current timestamp (based on custom default value)

$oof = new Foo([]);     // throws RepositoryException (bar is required)

可数组的

仓库对象提供了一个toArray方法,用于提取对象的非隐藏属性的属性名和值。

JsonSerializable

仓库对象实现了JsonSerializable接口。因此,你可以对它们进行编码,非隐藏受保护的属性将包含在由操作产生的JSON字符串中。

迭代器

仓库对象实现了Iterator接口。这允许你在foreach循环中使用它们。使用上面示例中定义的Foo对象...

$foo = new Foo(['bar' => 'Hello, World!']);

foreach ($foo as $field => $value) {
    echo "$field: $value" . PHP_EOL;
}

...将会产生...

bar: Hello, World!
bing: <timestamp>

...跳过baz属性,因为它被隐藏了。

dashifen/container

该对象是旧dashifen/container对象的新名称。为了避免与PSR-11 Container接口共享名称的任何混淆,我将名称从container更改为repository。所有关于此对象的未来工作都将在这里进行。如果你仍然在使用旧对象,我建议你切换代码并使用这个新版本。