首页
/ PHPStan中的PHPDoc基础指南

PHPStan中的PHPDoc基础指南

2025-07-06 03:06:08作者:齐添朝

什么是PHPDoc

PHPDoc是PHPStan静态分析工具的核心组成部分。虽然现代PHP版本已经通过原生类型提示(Typehints)能够表达很多类型信息,但PHPDoc仍然在补充类型信息方面发挥着重要作用。

PHPDoc注释必须以/**开头,使用/*//开头的注释不会被识别为PHPDoc。这是因为PHP解析器会将/**注释识别为特殊的T_DOC_COMMENT标记。

基本用法

方法和函数的PHPDoc

/**
 * @param User $user 用户对象
 * @return bool 是否操作成功
 */
function saveUser(User $user): bool { ... }

类属性的PHPDoc

/**
 * @var string 用户名
 */
private $username;

高级用法

内联@var注释

内联@var注释应当作为最后手段使用,因为它存在两个主要问题:

  1. PHPStan会完全信任它,如果注释有误会导致后续分析出错
  2. 需要在每个使用处重复注释

更好的做法是:

  1. 修复源头的类型定义
  2. 使用assert()进行运行时验证
// 不推荐的做法
/** @var User $user */
$user = getUser();

// 推荐的做法
$user = getUser();
assert($user instanceof User);

魔术属性和方法

对于通过__get/__set/__call实现的魔术方法,可以使用以下注释:

/**
 * @property int $id 用户ID
 * @property-read string $name 用户名
 * @method bool activate() 激活用户
 */
class User { ... }

异常处理

使用@throws标记可能抛出的异常:

/**
 * @throws InvalidArgumentException 当参数无效时抛出
 */
function validateInput($input) { ... }

类型组合

PHPDoc可以与原生类型提示结合使用,特别是在描述数组内容时:

/**
 * @param User[] $users 用户列表
 */
function processUsers(array $users) { ... }

// 也可以使用泛型语法
/**
 * @param array<int, User> $users 带键的用户列表
 */
function processUsersWithKeys(array $users) { ... }

泛型支持

PHPStan通过PHPDoc提供了强大的泛型支持:

/**
 * @template T
 * @param T $item
 * @return T
 */
function identity($item) { return $item; }

类型断言

PHPStan支持通过特殊注释进行类型断言:

/**
 * @phpstan-assert int $value
 */
function assertInt($value) {
    if (!is_int($value)) {
        throw new InvalidArgumentException();
    }
}

最佳实践

  1. 优先使用原生类型提示:PHP 7.4+支持属性类型提示,8.0+支持联合类型等
  2. 保持注释准确:错误的PHPDoc比没有PHPDoc更危险
  3. 避免过度使用内联@var:尽量修复源头类型问题
  4. 利用泛型:对于复杂数据结构特别有用
  5. 标记异常:帮助静态分析理解代码流程

特殊标记

PHPStan还支持一些特殊标记:

  • @deprecated:标记已弃用的元素
  • @internal:标记内部使用的元素
  • @readonly:在PHP 8.1前模拟只读属性
  • @immutable:标记不可变类

通过合理使用PHPDoc,可以极大提升PHPStan的静态分析效果,帮助开发者更早发现潜在问题,提高代码质量。