引言:为什么文档是你一个月后为自己编写的代码
每位PHP开发者都曾遇到过这样的情况:几个月前自己编写的代码,现在看来却像别人的代码一样难以理解。在高级开发阶段,文档不再仅仅是注释——它已成为项目架构的一部分、自动生成API参考的工具以及团队协作的基础。在本文中,我们将探讨如何为PHP项目创建不仅对新手有用,也对处理大型代码库的经验丰富的开发者有价值的文档。
我们将讨论PHPDoc标准(PSR-5和PSR-19)、自动生成工具(phpDocumentor、Doxygen),以及如何为使用接口、trait和抽象类的复杂项目结构化文档。
PHPDoc标准:PSR-5和PSR-19
对于专业的PHP文档,必须遵循公认的标准。其中最主要的是PSR-5(PHPDoc)和PSR-19(PHPDoc Tags)。PSR-5定义了文档块的语法和结构,而PSR-19则定义了推荐的标签列表。
基本标签及其高级用法
除了显而易见的@param、@return和@throws之外,在高级层面还经常使用:
- @method — 用于描述魔术方法(
__call、__get); - @property — 用于描述魔术属性;
- @template — 用于泛型编程(generics);
- @implements和@extends — 用于显式指定继承关系;
- @internal — 用于标记不供外部使用的代码。
<?php
/** * @template T of object * @implements CollectionInterface<T> */class EntityCollection implements CollectionInterface{ /** * @param array<int, T> $items */ public function __construct( private array $items = [] ) {}
/** * @return T|null */ public function first(): ?object { return $this->items[0] ?? null; }
/** * @method void sortBy(string $field) * @method T get(int $index) */ public function __call(string $name, array $arguments): mixed { // 魔术方法的实现 }}PHPDoc中的类型标注:从简单到复杂
高级文档需要精确的类型描述。请使用:
array<int, string>— 关联数组;Collection<User>— 对象集合;Closure(User): bool— 带有参数和返回值描述的闭包;class-string<User>— 包含类名的字符串。
复杂方法文档的示例:
/** * 根据给定条件过滤用户集合。 * * @param Closure(User): bool $callback 过滤函数 * @return static<User> 包含过滤后元素的新集合 * * @throws InvalidArgumentException 如果callback不可调用 * * @example * $admins = $users->filter(fn(User $u) => $u->isAdmin()); */public function filter(Closure $callback): static{ // ...}自动生成文档:phpDocumentor和Doxygen
手动保持文档的更新是一项很快就会变得难以承受的任务。自动生成工具允许直接从PHPDoc块创建HTML、PDF或Markdown格式的文档。
phpDocumentor (phpdoc)
最流行的PHP工具。通过Composer安装