本文介绍如何在 php 文件中以标准化、可维护的方式嵌入元数据(如作者、描述等),并提供高效、轻量的读取方案——利用 phpdoc 风格的首块多行注释,配合简易解析逻辑,避免全文件加载与正则遍历,兼顾性能与可读性。
PHP 本身不支持 HTML 那样的 标签语法,但社区早已形成成熟约定:使用 PHPDoc 风格的首块多行注释(`/ … */`)作为脚本级元数据容器**。这种写法不仅语义清晰、IDE 友好(支持自动提示与跳转),还能被主流工具链(如 phpDocumentor、PHPStan)识别,是事实上的行业标准。
例如,一个带元数据的 PHP 脚本可这样定义:
<?php /** * @author Ood * @copyright 2024 My Project * @version 1.2.0 * @desc Hello World 示例脚本,用于演示元数据提取 * @since PHP 8.1 */
要高效读取这些元数据,无需 file_get_contents() + 全文正则匹配。推荐采用「流式扫描 + 状态机」策略:逐行读取文件,仅解析开头部分,一旦遇到首个 */ 或非注释内容即终止。以下是一个轻量、健壮的实现示例:
function getPhpFileMeta(string $path): array
{
if (!is_file($path) || !is_readable($path)) {
return [];
}
$meta = [];
$inDocComment = false;
$handle = fopen($path, 'r');
while (($line = fgets($handle)) !== false) {
$trimmed = trim($line);
// 启动 PHPDoc 块
if (preg_match('/^\/\*\*[\s]*$/', $trimmed)) {
$inDocComment = true;
continue;
}
// 结束 PHPDoc 块
if ($inDocComment && preg_match('/^\*\/[\s]*$/', $trimmed)) {
break;
}
// 解析 @tag 行(支持空格/制表符缩进后的 @xxx)
if ($inDocComment && preg_match('/^\s*\*\s*@(\w+)\s+(.+)$/', $trimmed, $matches)) {
$key = strtolower($matches[1]);
$value = trim($matches[2]);
// 支持多行值(后续行以 * 开头且无 @,则追加到上一个 key)
if (isset($meta[$key]) && preg_match('/^\s*\*\s+(.+)$/', $trimmed, $cont)) {
$meta[$key] .= "\n" . trim($cont[1]);
} else {
$meta[$key] = $value;
}
}
// 遇到非注释行(如 Ood
// [copyright] => 2024 My Project
// [version] => 1.2.0
// [desc] => Hello World 示例脚本,用于演示元数据提取
// [since] => PHP 8.1
// )
✅ 优势说明: