升级 Valinor¶
从 1.x 升级到 2.x ¶
概括
- TL;DR — 重大变更的完整列表
- 消息/错误处理的更改
- 消息代码的更改
- 引入了
NormalizerBuilder作为规范化器的主要入口 - 删除了简单缓存 (PSR-16) 处理
- 删除了
MapperBuilder::enableFlexibleCasting() - 删除了
MapperBuilder::alter() - 将
@pure标记添加到MapperBuilder和NormalizerBuilder方法 - 删除了类和接口
- 标记为
@internal类构造函数
消息/错误处理的更改¶
对消息和错误的处理方式进行了一些更改。
现在,当映射期间发生错误时,可以更轻松地获取消息:
try {
(new \CuyZ\Valinor\MapperBuilder())->mapper()->map(/* … */);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
// Before (1.x):
$messages = \CuyZ\Valinor\Mapper\Tree\Message\Messages::flattenFromNode(
$error->node()
);
// After (2.x):
$messages = $error->messages();
}
一些从消息中访问信息的方法已被移动:
// Before (1.x):
$name = $message->node()->name();
$path = $message->node()->path();
$type = $message->node()->type();
$type = $message->node()->sourceValue();
// After (2.x):
$name = $message->name();
$path = $message->path();
$type = $message->type();
$type = $message->sourceValue();
消息代码的更改¶
映射过程中可能抛出的所有消息的代码均已更改。他们现在更具表现力。以下是更改及其替换的详尽列表:
1642183169→cannot_find_object_builder器1632903281→invalid_source1607027306→cannot_resolve_type_from_union1654273010→invalid_list_key1630678334→invalid_value1630946163→invalid_array_key1655449641→missing_value1736015505→value_is_empty_array1736015714→value_is_empty_list1710263908→value_is_not_null1618739163→value_is_not_iterable1710262975→too_many_resolved_types_from_union1655117782→unexpected_keys1630686564→cannot_parse_datetime_format
请注意,许多与无效标量值映射相关的错误消息现在都有一个特定的代码,而它以前是unknown 。
引入了NormalizerBuilder作为规范化器的主要入口¶
NormalizerBuilder类已经被引入,现在将成为实例化规范化器的主要入口。因此, MapperBuilder中用于配置和返回规范化器的方法已被删除。
此决定旨在明确区分映射器和规范化器配置 API,因为在使用这两种服务时可能会出现混淆。
NormalizerBuilder可以这样使用:
$normalizer = (new \CuyZ\Valinor\NormalizerBuilder())
->registerTransformer(
fn (\DateTimeInterface $date) => $date->format('Y/m/d')
)
->normalizer(\CuyZ\Valinor\Normalizer\Format::array())
->normalize($someData);
删除了简单缓存 (PSR-16) 处理¶
简单缓存 PSR 要求已从库中删除。这意味着外部 PSR 实现不能再与该库一起使用。
做出这个决定是因为缓存的条目总是生成 PHP 代码,这不是 PSR 的目的。当使用带有自定义实现的库时,这会导致混乱和不正确的行为。
该库现在使用自己的缓存接口,但提供的实现没有改变,因此升级应该非常简单。
提醒一下,这是在应用程序中注入缓存的方式:
$cache = new \CuyZ\Valinor\Cache\FileSystemCache('path/to/cache-directory');
if ($isApplicationInDevelopmentEnvironment) {
$cache = new \CuyZ\Valinor\Cache\FileWatchingCache($cache);
}
(new \CuyZ\Valinor\MapperBuilder())
->withCache($cache)
->mapper()
->map(SomeClass::class, [/* … */]);
另请注意,此更改导致了重构,这应该会提高文件监视功能的信心:以前,当文件在开发过程中发生更改时,缓存条目有时不会正确失效。现在这应该更好了。
删除了MapperBuilder::enableFlexibleCasting() ¶
该方法已被删除,取而代之的是三种不同的模式:
MapperBuilder::allowScalarValueCasting()MapperBuilder::allowNonSequentialList()MapperBuilder::allowUndefinedValues()
应使用上述方法来适应更具体的用例。
删除了MapperBuilder::alter() ¶
此功能已被删除,以支持更灵活和更强大的映射器转换器。
请注意, MapperBuilder::alter()从未被真正记录过,因此很有可能只有少数用户在使用它。
将@pure标记添加到MapperBuilder和NormalizerBuilder方法¶
@pure注释在之前的提交中被删除,原因如下:
由于当前使 PHPStan 和 Psalm 使用纯功能所需的开销,这些要求已被删除。
不幸的是,由于 PHPStan 和 Psalm 无法自动检测提供给
MapperBuilder可调用值是否是纯的,因此用户被迫手动添加@pure注释。这一决定旨在在图书馆的严格性和用户体验之间取得公平的平衡。
在与@pure爱好者讨论后,决定重新引入它们。这次,通过使用该库提供的开箱即用的插件,可以轻松抑制 PHPStan 和 Psalm 报告的错误。
要在 PHPStan 中全局抑制这些错误,必须将以下行添加到phpstan.neon :
要在 Psalm 中全局抑制这些错误,必须将以下行添加到psalm.xml中:
<xi:include href="qa/Psalm/valinor-psalm-suppress-pure-errors.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
删除的类和接口¶
以下类/接口是初始版本的一部分,但库未使用。尽管没有人应该使用它们,但它们是公共 API 的一部分,因此删除它们是一项重大更改。
\CuyZ\Valinor\Mapper\Source\IdentifiableSource\CuyZ\Valinor\Utility\Priority\HasPriority\CuyZ\Valinor\Utility\Priority\PrioritizedList
标记为@internal类构造函数¶
一些构造函数已被标记为@internal ,以便通过允许在不破坏公共 API 的情况下更改这些方法来简化将来的维护。
此更改不应影响用户,因为无论如何他们都不应该直接使用这些。
受影响的构造函数列表:
\CuyZ\Valinor\Mapper\Tree\Message\Messages::__construct\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::__construct\CuyZ\Valinor\Normalizer\ArrayNormalizer::__construct\CuyZ\Valinor\Normalizer\JsonNormalizer::__construct\CuyZ\Valinor\Normalizer\StreamNormalizer::__construct
完整的不兼容变更列表¶
- 删除了
\Psr\SimpleCache\CacheInterface依赖项 - 已删除
\CuyZ\Valinor\MapperBuilder::alter()- 使用
\CuyZ\Valinor\MapperBuilder::registerConverter代替
- 使用
- 已删除
\CuyZ\Valinor\MapperBuilder::enableFlexibleCasting()- 请改用以下方法:
\CuyZ\Valinor\MapperBuilder::allowScalarValueCasting()\CuyZ\Valinor\MapperBuilder::allowNonSequentialList()\CuyZ\Valinor\MapperBuilder::allowUndefinedValues()
- 请改用以下方法:
- 已删除
\CuyZ\Valinor\MapperBuilder::registerTransformer()- 使用
\CuyZ\Valinor\NormalizerBuilder代替
- 使用
- 已删除
\CuyZ\Valinor\MapperBuilder::normalizer()- 使用
\CuyZ\Valinor\NormalizerBuilder代替
- 使用
- 将
\CuyZ\Valinor\MapperBuilder::warmup()重命名为\CuyZ\Valinor\MapperBuilder::warmupCacheFor() - 已删除
\CuyZ\Valinor\Mapper\MappingError::node()- 使用
\CuyZ\Valinor\Mapper\MappingError::messages()代替
- 使用
- 添加了
\CuyZ\Valinor\Mapper\MappingError::type() - 添加了
\CuyZ\Valinor\Mapper\MappingError::source() - 删除了
\CuyZ\Valinor\Mapper\Tree\Node - 删除了
\CuyZ\Valinor\Mapper\Tree\NodeTraverser - 删除了
\CuyZ\Valinor\Mapper\Tree\Message\Messages::flattenFromNode() - 已删除
\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::node()- 请改用以下方法:
\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::name()\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::path()\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::type()\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::sourceValue()
- 请改用以下方法:
- 更改了
\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::__construct()签名 - 删除了
\CuyZ\Valinor\Mapper\Source\IdentifiableSource - 删除了
\CuyZ\Valinor\Utility\Priority\HasPriority - 删除了
\CuyZ\Valinor\Utility\Priority\PrioritizedList - 将
\CuyZ\Valinor\Mapper\Tree\Message\Messages::__construct标记为@internal - 将
\CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::__construct为@internal - 将
\CuyZ\Valinor\Normalizer\ArrayNormalizer::__construct标记为@internal - 将
\CuyZ\Valinor\Normalizer\JsonNormalizer::__construct标记为@internal - 将
\CuyZ\Valinor\Normalizer\StreamNormalizer::__construct标记为@internal