跳至正文

更新日志 2.5.0 — 2026 年 6 月 28 日

重要变更

此版本为库带来了一组新功能:

享受! 🎉


规范化器配置器支持

现在,规范化器可以使用一组配置器,镜像以前版本中引入的映射器配置器。每一个都可以通过configureWith()方法全局使用,也可以作为用于特定类或属性的特性在本地使用。

键大小写标准化

四个配置器将标准化对象的键标准化为给定情况。这对于遵循与 PHP 代码库中使用的命名约定不同的命名约定来公开数据非常有用。

配置器 示例
new NormalizeKeysToCamelCase() first_name → firstName
new NormalizeKeysToPascalCase() first_name → FirstName
new NormalizeKeysToSnakeCase() firstName → first_name
new NormalizeKeysToKebabCase() firstName → first-name

全局使用时,每个标准化对象的键都会被转换:

use CuyZ\Valinor\Normalizer\Configurator\NormalizeKeysToSnakeCase;
use CuyZ\Valinor\Normalizer\Format;
use CuyZ\Valinor\NormalizerBuilder;

$userAsArray = (new NormalizerBuilder())
    ->configureWith(new NormalizeKeysToSnakeCase())
    ->normalizer(Format::array())
    ->normalize($user);

// ['first_name' => 'John']

用作特性时,仅转换目标类的键:

use CuyZ\Valinor\Normalizer\Configurator\NormalizeKeysToSnakeCase;

#[NormalizeKeysToSnakeCase]
final readonly class User
{
    public function __construct(
        public string $firstName,
    ) {}
}

// ['first_name' => 'John']

日期和时间标准化

NormalizeDateTimeFormat配置器使用给定格式将任何DateTimeInterface实例规范化为字符串。

全局使用,标准化过程中遇到的每个日期和时间都被格式化:

use CuyZ\Valinor\Normalizer\Configurator\NormalizeDateTimeFormat;
use CuyZ\Valinor\Normalizer\Format;
use CuyZ\Valinor\NormalizerBuilder;

$userAsArray = (new NormalizerBuilder())
    ->configureWith(new NormalizeDateTimeFormat(DATE_ATOM))
    ->normalizer(Format::array())
    ->normalize($user);

// [
//     'name' => 'Jane Doe',
//     'createdAt' => '2000-01-01T00:00:00+00:00',
// ]

用作特性时,仅对目标属性进行格式化:

use CuyZ\Valinor\Normalizer\Configurator\NormalizeDateTimeFormat;

final readonly class User
{
    public function __construct(
        public string $name,

        #[NormalizeDateTimeFormat(DATE_ATOM)]
        public DateTimeInterface $createdAt,
    ) {}
}

形状列表类型支持

现在支持形状列表类型list{…} 。它的工作方式类似于指定结构的数组,但强制从0开始连续的整数键,使其成为描述类似元组的值列表的正确类型。

final readonly class SomeClass
{
    public function __construct(
        /** @var list{string, int, float} */
        public array $shapedList,

        /** @var list{0: string, 1: int} */
        public array $shapedListWithExplicitKeys,

        /** @var list{0: string, 1?: int} */
        public array $shapedListWithOptionalElement,

        /** @var list{string, int, ...} */
        public array $unsealedShapedList,

        /** @var list{string, int, ...list<float>} */
        public array $unsealedShapedListWithExplicitType,

        /** @var list{string, ...<float>} */
        public array $unsealedShapedListWithShorthandType,
    ) {}
}

key-of类型支持

现在支持key-of<T>类型。它从枚举、数组、列表和指定结构的数组(包括数组常量)中提取关键类型。它与 [PHPStan] 和 [Psalm] 接受的相同语法兼容。

enum SomeBackedEnum: string
{
    case FOO = 'foo';
    case BAR = 'bar';
}

final readonly class SomeClassWithConstants
{
    public const SOME_ARRAY = ['foo' => 1, 'bar' => 2];
}

final readonly class SomeClass
{
    public function __construct(
        // Accepts 'FOO' or 'BAR' (the case names of the enum)
        /** @var key-of<SomeBackedEnum> */
        public string $enumKey,

        // Accepts 'foo' or 'bar' (the keys of the shaped array)
        /** @var key-of<array{foo: string, bar: int}> */
        public string $shapedArrayKey,

        // Accepts the key type of the array (string here)
        /** @var key-of<array<string, int>> */
        public string $arrayKey,

        // Accepts 'foo' or 'bar' (the keys of the class constant array)
        /** @var key-of<SomeClassWithConstants::SOME_ARRAY> */
        public string $constantArrayKey,
    ) {}
}

新功能

  • 添加规范化器配置器ConvertDateTime ( bf688b )
  • 添加规范化器配置器NormalizeKeysToCamelCase ( b0d38f )
  • 添加规范化器配置器NormalizeKeysToKebabCase ( 9826ca )
  • 添加规范化器配置器NormalizeKeysToPascalCase ( 53bff2 )
  • 添加规范化器配置器NormalizeKeysToSnakeCase ( c831e0 )
  • 添加对key-of映射的支持 ( ff16b2 )
  • 添加对协变模板的支持 ( c31f24 )
  • 添加对形状列表类型( eeeb5c )的支持
  • 支持引用其他本地别名的本地别名类型( 757256 )
  • 支持类常量的空值( 5cd356 )
  • 支持带括号的联合类型( 21a04b )

错误修复

  • 通过函数反射防止内存泄漏( 6d36a0 )
  • 通过匹配参数对联合候选进行排名( 126cf7 )

内部的

  • 添加安全漏洞报告指南( b80e2a )
  • 记住父类定义( 17d8cf )
  • 将 int 移动到Shell外部的 float 铸造 ( f84e78 )

其他

  • 将ConvertDateTime配置器重命名为NormalizeDateTimeFormat ( b7683a )
  • 将ConvertKeysTo*Case配置器重命名为MapKeysTo*Case ( e38e06 )