跳至正文

更新日志 2.1.0 — 2025 年 7 月 23 日

重要变更

特性转换器

信息

在文档中获取映射转换器的常见示例。

可调用转换器允许在映射期间定位任何值,而属性转换器允许定位特定类或属性以进行更精细的控制。

为了被映射器检测到,必须首先通过添加AsConverter特性来注册特性类。

特性必须声明一个名为map方法,该方法遵循与可调用转换器相同的规则:强制的第一个参数和可选的第二个callable参数。

下面是一个特性转换器的示例,它根据特定的字符串输入将字符串输入转换为布尔值:

namespace My\App;

#[\CuyZ\Valinor\Mapper\AsConverter]
#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class CastToBool
{
    /**
     * @param callable(mixed): bool $next
     */
    public function map(string $value, callable $next): bool
    {
        $value = match ($value) {
            'yes', 'on' => true,
            'no', 'off' => false,
            default => $value,
        };

        return $next($value);
    }
}

final class User
{
    public string $name;

    #[\My\App\CastToBool]
    public bool $isActive;
}

$user = (new \CuyZ\Valinor\MapperBuilder())
    ->mapper()
    ->map(User::class, [
        'name' => 'John Doe',
        'isActive' => 'yes',
    ]);

$user->name === 'John Doe';
$user->isActive === true;

映射参数时,特性转换器也可以用在函数参数上:

function someFunction(string $name, #[\My\App\CastToBool] bool $isActive) {
    // …
};

$arguments = (new \CuyZ\Valinor\MapperBuilder())
    ->argumentsMapper()
    ->mapArguments(someFunction(...), [
        'name' => 'John Doe',
        'isActive' => 'yes',
    ]);

$arguments['name'] === 'John Doe';
$arguments['isActive'] === true;

当无法控制转换器特性类时,可以使用registerConverter方法来注册它。

(new \CuyZ\Valinor\MapperBuilder())
    ->registerConverter(\Some\External\ConverterAttribute::class)
    ->mapper()
    ->map(…);

还可以通过向注册方法提供接口名称来注册共享公共接口的特性。

namespace My\App;

interface SomeAttributeInterface {}

#[\Attribute]
final class SomeAttribute implements \My\App\SomeAttributeInterface {}

#[\Attribute]
final class SomeOtherAttribute implements \My\App\SomeAttributeInterface {}

(new \CuyZ\Valinor\MapperBuilder())
    // Registers both `SomeAttribute` and `SomeOtherAttribute` attributes
    ->registerConverter(\My\App\SomeAttributeInterface::class)
    ->mapper()
    ->map(…);

新功能

  • 引入特性转换器以在映射期间进行粒度控制( 0a8c0d )

错误修复

  • 正确检测映射转换器返回的无效值( e80de7 )
  • 读取类型时正确提取=标记( 9a511d )
  • 使用 polyfill 进行array_find ( 540741 )

其他

  • 将异常标记为@internal ( f3eace )