切换至PHP属性实现OpenApi后,如何解决PHPStan数组类型错误?
解决PHP属性+Swagger下PHPStan Level 6数组类型报错问题
我在用Swagger创建OpenAPI文档时,从注解切换到PHP属性后,PHPStan Level 6检测数组属性时提示缺少具体类型声明,但用旧注解时完全正常。
示例代码
<?php declare(strict_types=1); namespace App\Api\Dto; use OpenApi\Attributes as OA; #[OA\Schema()] class UserDto implements DtoInterface { #[OA\Property(description: 'Personalnummer ', type: 'string')] public ?string $uid = null; #[OA\Property(description: 'Name,Vorname', type: 'string')] public ?string $username = null; #[OA\Property(description: 'Stammhaus', type: 'string')] public ?string $mainhouse = null; #[OA\Property(description: 'Name, Vorname', type: 'integer')] public ?int $companyId = null; #[OA\Property(description: 'Symfony Rollen in der Applikation', type: 'array')] /** @var array<string> */ public array $roles = []; #[OA\Property(description: 'Rechte', type: 'array', items: new OA\Items(type: 'string'))] /** @var array<string> */ public array $grants = []; #[OA\Property(description: 'Ressourcen', type: 'array')] /** @var array<string, array<string>> */ public array $resources = []; }
PHPStan报错信息
------ --------------------------------------------------------------------------------------------------- Line Api/Dto/UserDto.php ------ --------------------------------------------------------------------------------------------------- 26 Property App\Api\Dto\UserDto::$roles type has no value type specified in iterable type array. 💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type 29 Property App\Api\Dto\UserDto::$grants type has no value type specified in iterable type array. 💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type 33 Property App\Api\Dto\UserDto::$resources type has no value type specified in iterable type array. 💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type ------ ---------------------------------------------------------------------------------------------------
解决方案
你的环境是PHP 8.2,支持原生泛型数组类型声明,直接替换掉PHPDoc注解,在array后通过<>明确数组元素类型即可,PHPStan会直接识别该类型,无需额外注解就能通过Level 6检测。
修改后的代码如下:
<?php declare(strict_types=1); namespace App\Api\Dto; use OpenApi\Attributes as OA; #[OA\Schema()] class UserDto implements DtoInterface { #[OA\Property(description: 'Personalnummer ', type: 'string')] public ?string $uid = null; #[OA\Property(description: 'Name,Vorname', type: 'string')] public ?string $username = null; #[OA\Property(description: 'Stammhaus', type: 'string')] public ?string $mainhouse = null; #[OA\Property(description: 'Name, Vorname', type: 'integer')] public ?int $companyId = null; #[OA\Property(description: 'Symfony Rollen in der Applikation', type: 'array')] public array<string> $roles = []; #[OA\Property(description: 'Rechte', type: 'array', items: new OA\Items(type: 'string'))] public array<string> $grants = []; #[OA\Property(description: 'Ressourcen', type: 'array')] public array<string, array<string>> $resources = []; }
如果因特殊情况无法使用原生泛型,可确保PHPDoc的@var注解与属性声明严格匹配,同时检查PHPStan配置中是否开启了PHPDoc类型解析,但原生泛型是最简洁且符合PHP 8+特性的方案。
内容的提问来源于stack exchange,提问作者Calamity Jane
相关产品推荐
相关产品推荐

