php无内置函数可智能修改注释,需结合file_get_contents()读取、正则匹配(如/^/**(.?)*/s$/ms)定位并替换/**/块注释,或用Token_get_all()安全提取T_DOC_COMMENT;批量处理时须过滤vendor等目录,并人工校验注释用途。

直接替换文件中的注释块需要正则匹配
PHP 本身没有内置函数能“智能修改注释”,必须靠读取文件内容 + 正则定位注释区域 + 字符串替换实现。关键在于准确识别注释边界,否则容易误删代码或破坏结构。
PHP 支持三种常见注释格式:// 行注释、# 行注释、/* */ 块注释。其中只有 /* */ 跨行且可嵌套(实际不支持嵌套,但多行匹配易出错),最常用于文件头注释,也是修改需求最集中的地方。
- 用
file_get_contents()读整个文件,避免逐行处理丢失上下文 - 对
/* */注释,推荐用非贪婪正则://**(?:[^*]|*(?!/))**//s,匹配以/**开头、*/结尾的文档块注释(如 PHPDoc) - 若只想换文件头(通常在文件最开头),加锚点
^提高精度:/^/**(?:[^*]|*(?!/))**//ms - 替换前务必用
backup文件或git stash,正则写错可能清空整段逻辑
修改 PHPDoc 注释时注意 @tag 顺序和缩进一致性
很多项目要求文件头包含 @package、@author、@since 等标签,手动拼接字符串容易导致格式错乱。直接用 str_replace() 会破坏原有缩进或换行,建议提取后重建。
示例:只更新 @author 字段,其他保持原样:
立即学习“PHP免费学习笔记(深入)”;
$content = file_get_contents('Example.php'); if (preg_match('/^/**(.*?)*/s*$/ms', $content, $matches)) { $docblock = $matches[1]; // 提取并重写 @author 行,其余行保留 $lines = explode("n", trim($docblock)); $newLines = []; foreach ($lines as $line) { if (strpos(trim($line), '@author') === 0) { $newLines[] = ' * @author New Name '; } else { $newLines[] = $line; } } $newDocblock = implode("n", $newLines); $content = preg_replace('/^/**(.*?)*/s*$/ms', "/**n{$newDocblock}n */", $content, 1); file_put_contents('Example.php', $content); }
用 token_get_all() 安全提取注释(适合复杂场景)
当文件里混用多种注释、或存在字符串中含 /* 等干扰内容时,正则容易误匹配。token_get_all() 能按 PHP 语法解析真实注释 Token,更可靠。
- 它返回数组,每个元素是
[TOKEN_NAME, content, line_number]三元组 - 注释对应的 Token 是
T_COMMENT(//和#)和T_DOC_COMMENT(/** */) - 需遍历 Token 流,记录第一个
T_DOC_COMMENT的位置和长度,再用substr_replace()替换 - 缺点是不能直接改内容结构(比如只动某个
@tag),得先解析注释文本再重组
批量修改多个文件要避开 symlink 和 vendor 目录
用 glob() 或 RecursiveDirectoryIterator 扫描时,不加过滤会误改第三方库注释,甚至破坏 symlink 指向的原始文件。
- 排除
vendor/、node_modules/、.git/等目录,可用is_dir()+ 名称判断 - 检查是否为真实文件:
!is_link($path) && is_file($path) - 限定扩展名:
pathinfo($file, PATHINFO_EXTENSION) === 'php' - 写入前加
if (strpos($content, '/**') !== false)快速跳过不含 PHPDoc 的文件,省性能
真正难的不是怎么写正则,而是判断哪段注释该动、哪段是生成代码留下的、哪段被 ide 锁定了——这些没法靠通用脚本解决,得结合项目规范人工校验。