应使用 token_get_all() 提取 T_DOC_COMMENT 类型的 PHP 文档注释,因其能准确区分 PHPDoc 与普通注释、字符串等内容,避免正则误匹配;再用 preg_replace 清洗标签并规范化空白。

只提取 PHP 中的文档注释(T_DOC_COMMENT)
想从 PHP 源码里单独拎出 /** ... */ 这类文档注释(比如 PHPDoc),不能靠通用注释正则,得先区分类型。PHP 的 token_get_all() 能准确识别 T_DOC_COMMENT,而把普通 // 或 /* ... */ 当作 T_COMMENT 处理——这是最稳的方式。
直接用正则硬抓 /\*\*.*?\*\//s 看似简单,但容易误匹配非文档注释,比如:
/* 这只是普通块注释,不是 PHPDoc */ $var = "/* 里面还有星号和斜杠 */";
这种字符串内容会被错误捕获。
- 用
token_get_all()遍历所有 token,只收集T_DOC_COMMENT类型的值 - 跳过
T_COMMENT(普通注释)、T_INLINE_HTML(混入的 HTML)、T_STRING(代码本身) - 注意:
token_get_all()输入必须是合法 PHP 代码,否则会提前中断或返回空数组
过滤掉 @param、@return 等 PHPDoc 标签后只留描述文本
提取到完整 PHPDoc 后,下一步常是清洗——去掉 @param、@return、@throws 等标签行,只保留纯描述段落。这不是简单删关键词,因为标签可能跨行,也可能带缩进或换行符。
立即学习“PHP免费学习笔记(深入)”;
推荐分两步走:
- 先用
preg_replace('/^\s*\@(?:param|return|throws|see|link|deprecated|since|version|author).*?$/m', '', $doc)清除整行标签(m修饰符让^$匹配每行头尾) - 再用
preg_replace('/\s+/', ' ', $cleaned)合并多余空白,并trim()去首尾空格 - 别用
.*贪婪匹配整个 PHPDoc 块,否则会把标签后面的说明文字也吞掉
为什么不用 strip_comments()?它根本不存在
网上有些文章提到 strip_comments() 是 PHP 内置函数,这是错的。PHP 官方从未提供这个函数,也没有 strip_comments 扩展。你运行 function_exists('strip_comments') 会返回 false。
混淆可能来自两个地方:
- 某些第三方库(如 PHP-Parser)提供了
stripComments()方法,但那是对象实例方法,不是全局函数 - OPcache 配置项
opcache.save_comments=0会让 opcode 层不保存注释,但这不影响源码本身,也不能用于提取 - 误把
token_get_all()的结果手动过滤当成“内置 strip”
正则提取时最容易漏掉的三种情况
哪怕用了 /\*\*.*?\*\//s,也会在这些边界场景翻车:
-
/** @var string $foo */ $foo = '';—— 注释紧贴代码无换行,正则能抓到,但后续清洗时若没处理好末尾*/后的空格/分号,会导致语法错位 /** 多行<br>PHPDoc */
—— 实际含 HTML 换行符或 \r\n 混用,s修饰符虽支持.匹配换行,但若原始字符串没统一换行符,file_get_contents()读出来可能断在奇怪位置-
/** 注释里有 /* 嵌套 */ */—— 真实 PHP 不允许嵌套,但正则/\*\*.*?\*\//s会停在第一个*/,导致截断;正确做法是依赖token_get_all(),它按真实词法解析,天然规避该问题
真正要提取文档注释,别省那几行代码——token_get_all() 是唯一靠谱起点,其余都是妥协方案。



















