inspirum/arrayable

PHP 数组转换接口,用于处理对象转换为数组

v1.3.0 2024-09-05 11:29 UTC

This package is auto-updated.

Last update: 2024-09-05 11:42:20 UTC


README

Latest Stable Version Build Status Coverage Status Quality Score PHPStan Total Downloads Software License

动机

不幸的是,PHP 没有很好地将对象转换为类型的方法。

__toString() 魔法方法用于 \Stringable 接口(自 PHP 8.0 开始)和 jsonSerialize() 方法用于 \JsonSerializable 接口(自 PHP 5.4 开始),但 __toArray() 方法目前(以及将来)不支持 - 只有一些被拒绝的草案 RFC(object_cast_to_typesto array 等)建议进行对象到标量类型的转换。

但到目前为止(至少)还没有一种方法可以实现当转换为 array 时被调用的方法。

理想情况下,以下内容应该工作

class Person
{
    public function __construct(
        public string $name,
        protected string $username,
        private string $password,
    ) {}
 
    public function __toArray(): array
    {
        return [
            'name' => $this->name,
            'email' => $this->username,
        ];
    }
}

$person = new Person('John Doe', 'j.doe@example.com', 'secret_pwd');

$personArray = (array) $person; // casting triggers __toArray()

/**
var_dump($personArray);
[
  'name' => 'John Doe'
  'email' => 'j.doe@example.com'
]
*/

但实际上它转换为数组如下

/**
var_dump($personArray);
[
  'name' => 'John Doe'
  '*username' => 'j.doe@example.com'
  'Person@password' => 'secret_pwd'
]
*/

用法示例

这里显示的所有代码片段都已修改以供清晰理解,因此它们可能无法执行。

此包实现了简单的 \Arrayable(或 \Inspirum\Arrayable\Arrayable)接口。

/** @implements \Arrayable<string, string> */
class Person implements \Arrayable
{
    public function __construct(
        public string $name,
        protected string $username,
        protected string $password,
    ) {}
 
    /** @return array<string, string> */
    public function __toArray(): array
    {
        return [
            'name' => $this->name,
            'email' => $this->username,
        ];
    }
}

$person = new Person('John Doe', 'j.doe@example.com', 'secret_pwd');

存在 \is_arrayable() 函数(或 \Inspirum\Arrayable\Convertor::isArrayable() 方法)来检查给定数据是否能够将自己转换为 array

var_dump(\is_arrayable([1, 2, 3])); // bool(true)
var_dump(\is_arrayable(new \ArrayIterator([1, 2, 3]))); // bool(true)
var_dump(\is_arrayable(new \ArrayObject([4, 5, 6]))); // bool(true)
var_dump(\is_arrayable((function () { yield 1; })())); // bool(true)
var_dump(\is_arrayable(1)); // bool(false)
var_dump(\is_arrayable(new \stdClass())); // bool(false)
var_dump(\is_arrayable(new class {})); // bool(false)
var_dump(\is_arrayable(new class implements \Arrayable {})); // bool(true)
var_dump(\is_arrayable($person); // bool(true)

然后有 \to_array() 函数(或 \Inspirum\Arrayable\Convertor::toArray() 方法)来递归地将数据转换为 array

$data = \to_array(new \ArrayIterator([1, $person, (object) ['a' => true]]));

/**
var_dump($data);
[
  0 => 1
  1 => [ 
    'name' => 'John Doe'
    'email' => 'j.doe@example.com'
  ]
  2 => [
   'a' => true
  ]
*/

此外,还有一些用于 DAO(BaseModel)和集合(BaseCollection)对象的常用辅助抽象类。

系统需求

安装

运行 composer require 命令

$ composer require inspirum/arrayable

测试

要运行单元测试,请运行

$ composer test:test

要显示覆盖率,请运行

$ composer test:coverage

贡献

请参阅 CONTRIBUTINGCODE_OF_CONDUCT 以获取详细信息。

安全性

如果您发现任何与安全相关的问题,请通过电子邮件发送至 tomas.novotny@inspirum.cz,而不是使用问题跟踪器。

致谢

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件