静态分析¶
为了帮助使用此库对代码库进行静态分析,提供了 [PHPStan] 扩展和 [Psalm] 插件。它们使这些工具能够更好地理解映射器的行为。
注意
要激活此功能,必须正确注册插件:
考虑到项目中至少安装了其中一个工具,下面是将报告的错误类型的示例。
映射到类数组
final readonly class SomeClass
{
public function __construct(
public string $foo,
public int $bar,
) {}
}
$objects = (new \CuyZ\Valinor\MapperBuilder())
->mapper()
->map(
'array<' . SomeClass::class . '>',
[/* … */]
);
foreach ($objects as $object) {
// ✅
echo $object->foo;
// ✅
echo $object->bar * 2;
// ❌ Cannot perform operation between `string` and `int`
echo $object->foo * $object->bar;
// ❌ Property `SomeClass::$fiz` is not defined
echo $object->fiz;
}
映射到指定结构的数组
$array = (new \CuyZ\Valinor\MapperBuilder())
->mapper()
->map(
'array{foo: string, bar: int}',
[/* … */]
);
// ✅
echo $array['foo'];
// ❌ Expected `string` but got `int`
echo strtolower($array['bar']);
// ❌ Cannot perform operation between `string` and `int`
echo $array['foo'] * $array['bar'];
// ❌ Offset `fiz` does not exist on array
echo $array['fiz'];
映射可调用对象的参数
$someFunction = function(string $foo, int $bar): string {
return "$foo / $bar";
};
$arguments = (new \CuyZ\Valinor\MapperBuilder())
->argumentsMapper()
->mapArguments($someFunction, [
'foo' => 'some value',
'bar' => 42,
]);
// ✅ Arguments have a correct shape, no error reported
echo $someFunction(...$arguments);
关于映射器和规范化器纯度¶
映射器和规范化器被设计为纯粹的,这意味着它们没有副作用,并且对于相同的输入始终返回相同的结果。有关更多信息,请参阅纯函数的定义。
建议在开发应用程序时通过使用 [PHPStan] 和 [Psalm] 处理的@pure注释来牢记纯度。
映射用户提供的数据本身就是一个潜在危险的操作:通过仅依赖纯函数/类型进行映射,可以确保恶意用户输入在调用TreeMapper::map()时不会造成副作用。您可以自由地抑制/忽略给定的纯度准则,但代价是扩大攻击面。
在某些情况下,纯度分析可能会返回误报,这些误报很容易被忽略,例如通过使用@phpstan-ignore和@psalm-suppress注释。