我来帮你创建一个PHP Markdown文档生成工具,这个工具可以方便地将PHP代码转换为格式化的Markdown文档。

完整实现方案
基础Markdown生成器类
<?php
/**
* MarkdownDocumenter - PHP代码文档生成器
*
* 自动从PHP源代码生成Markdown格式的文档
*/
class MarkdownDocumenter {
/** @var string 生成的文档内容 */
private $documentation = '';
/** @var array 解析的类信息 */
private $classInfo = [];
/** @var array 函数信息 */
private $functionInfo = [];
/**
* 从PHP文件生成Markdown文档
*
* @param string $filePath PHP文件路径
* @return string Markdown内容
*/
public function generateFromFile($filePath) {
if (!file_exists($filePath)) {
return "错误: 文件不存在";
}
$content = file_get_contents($filePath);
return $this->generateFromSource($content);
}
/**
* 从源代码生成Markdown文档
*
* @param string $source PHP源代码
* @return string Markdown内容
*/
public function generateFromSource($source) {
$this->documentation = '';
$this->classInfo = [];
$this->functionInfo = [];
// 提取PHP代码块
preg_match_all('/<\?php(.*?)(?:\?>|$)/s', $source, $matches);
foreach ($matches[1] as $phpCode) {
$this->analyzeCode($phpCode);
}
$this->buildDocumentation();
return $this->documentation;
}
/**
* 分析PHP代码
*
* @param string $code PHP代码
*/
private function analyzeCode($code) {
// 提取注释块
preg_match_all('/\/\*\*(.*?)\*\//s', $code, $docBlocks, PREG_OFFSET_CAPTURE);
// 提取类定义
preg_match_all('/class\s+(\w+)(?:\s+extends\s+(\w+))?(?:\s+implements\s+([^{]+))?/i', $code, $classes, PREG_OFFSET_CAPTURE);
// 提取接口定义
preg_match_all('/interface\s+(\w+)/i', $code, $interfaces, PREG_OFFSET_CAPTURE);
// 提取trait定义
preg_match_all('/trait\s+(\w+)/i', $code, $traits, PREG_OFFSET_CAPTURE);
// 提取函数定义
preg_match_all('/function\s+(\w+)\s*\(([^)]*)\)/i', $code, $functions, PREG_OFFSET_CAPTURE);
// 处理类
if (!empty($classes[1])) {
foreach ($classes[1] as $index => $class) {
$className = $class[0];
$line = $this->getLineNumber($code, $class[1]);
$info = [
'name' => $className,
'line' => $line,
'extends' => isset($classes[2][$index][0]) ? $classes[2][$index][0] : null,
'implements' => isset($classes[3][$index][0]) ? $classes[3][$index][0] : null,
'methods' => [],
'properties' => []
];
// 提取类的方法
$this->extractMethods($code, $class[1], $info);
// 提取类的属性
$this->extractProperties($code, $class[1], $info);
$this->classInfo[] = $info;
}
}
// 处理接口
if (!empty($interfaces[1])) {
foreach ($interfaces[1] as $index => $interface) {
$interfaceName = $interface[0];
$line = $this->getLineNumber($code, $interface[1]);
$info = [
'name' => $interfaceName,
'line' => $line,
'type' => 'interface',
'methods' => []
];
$this->extractMethods($code, $interface[1], $info);
$this->classInfo[] = $info;
}
}
// 处理trait
if (!empty($traits[1])) {
foreach ($traits[1] as $index => $trait) {
$traitName = $trait[0];
$line = $this->getLineNumber($code, $trait[1]);
$info = [
'name' => $traitName,
'line' => $line,
'type' => 'trait',
'methods' => []
];
$this->extractMethods($code, $trait[1], $info);
$this->classInfo[] = $info;
}
}
// 处理函数
if (!empty($functions[1])) {
foreach ($functions[1] as $index => $function) {
$functionName = $function[0];
$line = $this->getLineNumber($code, $function[1]);
$params = $functions[2][$index][0];
$this->functionInfo[] = [
'name' => $functionName,
'line' => $line,
'params' => $params
];
}
}
}
/**
* 提取类方法
*
* @param string $code PHP代码
* @param int $classOffset 类定义偏移量
* @param array &$info 类信息引用
*/
private function extractMethods($code, $classOffset, &$info) {
// 查找类定义的位置
$classPos = strpos($code, 'class', $classOffset);
if ($classPos === false) {
$classPos = strpos($code, 'interface', $classOffset);
}
if ($classPos === false) {
$classPos = strpos($code, 'trait', $classOffset);
}
if ($classPos !== false) {
// 查找类的开始花括号
$bracePos = strpos($code, '{', $classPos);
if ($bracePos !== false) {
// 提取类内的方法
$endPos = $this->findMatchingBrace($code, $bracePos);
$classContent = substr($code, $bracePos, $endPos - $bracePos);
preg_match_all('/function\s+(\w+)\s*\(([^)]*)\)/i', $classContent, $methods, PREG_OFFSET_CAPTURE);
foreach ($methods[1] as $mIndex => $method) {
$methodName = $method[0];
$methodParams = $methods[2][$mIndex][0];
// 提取可见性
$methodVisibility = $this->getVisibility($classContent, $methods[0][$mIndex][1]);
$info['methods'][] = [
'name' => $methodName,
'params' => $methodParams,
'visibility' => $methodVisibility,
'static' => $this->isStatic($classContent, $methods[0][$mIndex][1])
];
}
}
}
}
/**
* 提取类属性
*
* @param string $code PHP代码
* @param int $classOffset 类定义偏移量
* @param array &$info 类信息引用
*/
private function extractProperties($code, $classOffset, &$info) {
$classPos = strpos($code, 'class', $classOffset);
if ($classPos !== false) {
$bracePos = strpos($code, '{', $classPos);
if ($bracePos !== false) {
$endPos = $this->findMatchingBrace($code, $bracePos);
$classContent = substr($code, $bracePos, $endPos - $bracePos);
preg_match_all('/(?:public|protected|private|var)\s+\$(\w+)/i', $classContent, $properties);
foreach ($properties[1] as $property) {
$info['properties'][] = $property;
}
}
}
}
/**
* 获取方法可见性
*
* @param string $content 类内容
* @param int $offset 方法偏移量
* @return string 可见性
*/
private function getVisibility($content, $offset) {
$beforeMethod = substr($content, 0, $offset);
if (preg_match('/(public|protected|private)\s+function\s*$/', $beforeMethod)) {
preg_match('/(public|protected|private)\s+function\s*$/', $beforeMethod, $matches);
return $matches[1];
}
return 'public'; // 默认public
}
/**
* 检查方法是否为static
*
* @param string $content 类内容
* @param int $offset 方法偏移量
* @return bool 是否为static
*/
private function isStatic($content, $offset) {
$beforeMethod = substr($content, 0, $offset);
return (bool)preg_match('/static\s+function\s*$/', $beforeMethod);
}
/**
* 查找匹配的花括号
*
* @param string $code PHP代码
* @param int $bracePos 开始花括号位置
* @return int 匹配花括号位置
*/
private function findMatchingBrace($code, $bracePos) {
$depth = 1;
$pos = $bracePos;
while ($depth > 0 && $pos < strlen($code)) {
$pos++;
if ($code[$pos] === '{') {
$depth++;
} elseif ($code[$pos] === '}') {
$depth--;
}
}
return $pos;
}
/**
* 获取代码行号
*
* @param string $code PHP代码
* @param int $offset 偏移量
* @return int 行号
*/
private function getLineNumber($code, $offset) {
$before = substr($code, 0, $offset);
return substr_count($before, "\n") + 1;
}
/**
* 构建Markdown文档
*/
private function buildDocumentation() {
$this->documentation = "# PHP 代码文档\n\n";
$this->documentation .= "> 自动生成的代码文档\n\n";
// 目录
$this->documentation .= "## 目录\n\n";
if (!empty($this->classInfo)) {
$this->documentation .= "### 类 \n";
foreach ($this->classInfo as $class) {
$this->documentation .= "- [{$class['name']}](#" . strtolower($class['name']) . ")\n";
}
}
if (!empty($this->functionInfo)) {
$this->documentation .= "### 函数\n";
foreach ($this->functionInfo as $function) {
$this->documentation .= "- [{$function['name']}()](#" . strtolower($function['name']) . ")\n";
}
}
$this->documentation .= "\n---\n\n";
// 类文档
if (!empty($this->classInfo)) {
$this->documentation .= "## 类\n\n";
foreach ($this->classInfo as $class) {
$this->documentation .= "### {$class['name']}\n\n";
if (isset($class['type'])) {
$this->documentation .= "**类型**: {$class['type']}\n\n";
}
$this->documentation .= "- **文件位置**: 第 {$class['line']} 行\n\n";
if (isset($class['extends']) && $class['extends']) {
$this->documentation .= "- **继承自**: `{$class['extends']}`\n\n";
}
if (isset($class['implements']) && $class['implements']) {
$this->documentation .= "- **实现**: `{$class['implements']}`\n\n";
}
// 属性
if (!empty($class['properties'])) {
$this->documentation .= "#### 属性\n\n";
foreach ($class['properties'] as $property) {
$this->documentation .= "- `\${$property}`\n";
}
$this->documentation .= "\n";
}
// 方法
if (!empty($class['methods'])) {
$this->documentation .= "#### 方法\n\n";
foreach ($class['methods'] as $method) {
$visibility = isset($method['visibility']) ? $method['visibility'] : 'public';
$static = isset($method['static']) && $method['static'] ? 'static ' : '';
$this->documentation .= "##### `{$visibility} {$static}function {$method['name']}({$method['params']})`\n\n";
}
$this->documentation .= "\n";
}
$this->documentation .= "---\n\n";
}
}
// 函数文档
if (!empty($this->functionInfo)) {
$this->documentation .= "## 函数\n\n";
foreach ($this->functionInfo as $function) {
$this->documentation .= "### {$function['name']}()\n\n";
$this->documentation .= "- **文件位置**: 第 {$function['line']} 行\n";
$this->documentation .= "- **参数**: `{$function['params']}`\n\n";
$this->documentation .= "---\n\n";
}
}
}
/**
* 添加自定义内容
*
* @param string $content 要添加的内容
*/
public function addContent($content) {
$this->documentation .= $content . "\n\n";
}
/**
* 保存文档到文件
*
* @param string $filename 文件名
* @return bool 是否成功
*/
public function saveToFile($filename) {
return file_put_contents($filename, $this->documentation) !== false;
}
/**
* 获取最终文档
*
* @return string Markdown内容
*/
public function getDocumentation() {
return $this->documentation;
}
}
高级Markdown生成器(带样式和模板)
<?php
/**
* AdvancedMarkdownGenerator - 高级Markdown文档生成器
*
* 支持自定义模板、代码高亮、表格生成等功能
*/
class AdvancedMarkdownGenerator {
private $template;
private $content = [];
private $toc = [];
public function __construct() {
$this->setDefaultTemplate();
}
/**
* 设置模板
*
* @param string $template 模板内容
*/
public function setTemplate($template) {
$this->template = $template;
}
/**
* 设置默认模板
*/
private function setDefaultTemplate() {
$this->template = "# {{TITLE}}\n\n"
. "> {{DESCRIPTION}}\n\n"
. "## 目录\n\n"
. "{{TOC}}\n\n"
. "---\n\n"
. "{{CONTENT}}";
}
/**
* 生成文档
*
* @param array $data 文档数据
* @return string 生成的Markdown
*/
public function generate($data) {
$title = isset($data['title']) ? $data['title'] : '文档';
$description = isset($data['description']) ? $data['description'] : '自动生成的文档';
// 替换模板变量
$output = str_replace('{{TITLE}}', $title, $this->template);
$output = str_replace('{{DESCRIPTION}}', $description, $output);
// 生成目录
$tocContent = $this->generateTOC($data['sections']);
$output = str_replace('{{TOC}}', $tocContent, $output);
// 生成内容
$content = $this->generateContent($data['sections']);
$output = str_replace('{{CONTENT}}', $content, $output);
return $output;
}
/**
* 生成目录
*
* @param array $sections 文档段落
* @return string 目录Markdown
*/
private function generateTOC($sections) {
$toc = "";
foreach ($sections as $section) {
$toc .= "- [" . $section['title'] . "](#" . $this->slugify($section['title']) . ")\n";
}
return $toc;
}
/**
* 生成内容
*
* @param array $sections 文档段落
* @return string 内容Markdown
*/
private function generateContent($sections) {
$content = "";
foreach ($sections as $section) {
$content .= "## " . $section['title'] . "\n\n";
$content .= $section['content'] . "\n\n";
}
return $content;
}
/**
* 生成表格
*
* @param array $headers 表头
* @param array $rows 数据行
* @return string 表格Markdown
*/
public function generateTable($headers, $rows) {
$table = "| " . implode(" | ", $headers) . " |\n";
$table .= "|" . str_repeat("---|", count($headers)) . "\n";
foreach ($rows as $row) {
$table .= "| " . implode(" | ", array_map('strval', $row)) . " |\n";
}
return $table;
}
/**
* 生成代码块
*
* @param string $code 代码内容
* @param string $language 语言类型
* @return string 代码块Markdown
*/
public function generateCodeBlock($code, $language = 'php') {
return "```{$language}\n{$code}\n```";
}
/**
* 生成链接
*
* @param string $text 显示文本
* @param string $url URL地址
* @return string 链接Markdown
*/
public function generateLink($text, $url) {
return "[{$text}]({$url})";
}
/**
* 生成图片
*
* @param string $src 图片路径
* @param string $alt 替代文本
* @return string 图片Markdown
*/
public function generateImage($src, $alt = '') {
return "";
}
/**
* 生成分隔线
*
* @return string 分隔线Markdown
*/
public function generateDivider() {
return "---";
}
/**
* 生成引用块
*
* @param string $text 引用文本
* @return string 引用Markdown
*/
public function generateBlockquote($text) {
return "> " . $text;
}
/**
* 生成列表
*
* @param array $items 列表项
* @param bool $ordered 是否有序
* @return string 列表Markdown
*/
public function generateList($items, $ordered = false) {
$list = "";
if ($ordered) {
foreach ($items as $index => $item) {
$list .= ($index + 1) . ". {$item}\n";
}
} else {
foreach ($items as $item) {
$list .= "- {$item}\n";
}
}
return $list;
}
/**
* 生成任务列表
*
* @param array $tasks 任务列表
* @return string 任务列表Markdown
*/
public function generateTaskList($tasks) {
$list = "";
foreach ($tasks as $task => $done) {
$checkbox = $done ? '[x]' : '[ ]';
$list .= "- {$checkbox} {$task}\n";
}
return $list;
}
/**
* 生成嵌套列表
*
* @param array $items 项目列表(支持嵌套)
* @return string 嵌套列表Markdown
*/
public function generateNestedList($items, $level = 0) {
$list = "";
$indent = str_repeat(" ", $level);
foreach ($items as $item) {
if (is_array($item)) {
$list .= $indent . "- " . $item['title'] . "\n";
if (isset($item['children'])) {
$list .= $this->generateNestedList($item['children'], $level + 1);
}
} else {
$list .= $indent . "- " . $item . "\n";
}
}
return $list;
}
/**
* 生成锚点链接
*
* @param string $text 显示文本
* @param string $anchor 锚点名称
* @return string 锚点Markdown
*/
public function generateAnchorLink($text, $anchor) {
return "[{$text}](#{$this->slugify($anchor)})";
}
/**
* 生成脚注
*
* @param string $text 脚注文本
* @param int $number 脚注编号
* @return string 脚注Markdown
*/
public function generateFootnote($text, $number = null) {
if ($number === null) {
$number = count($this->footnotes) + 1;
}
$this->footnotes[$number] = $text;
return "[^{$number}]";
}
/**
* 获取所有脚注
*
* @return string 脚注段落
*/
public function getFootnotes() {
$output = "\n---\n\n## 脚注\n\n";
foreach ($this->footnotes as $number => $text) {
$output .= "[^{$number}]: {$text}\n";
}
return $output;
}
/**
* 转换字符串为slug
*
* @param string $text 原始字符串
* @return string slug字符串
*/
private function slugify($text) {
$text = strtolower(trim($text));
$text = preg_replace('/[^a-z0-9\s-]/', '', $text);
$text = preg_replace('/[\s-]+/', '-', $text);
return $text;
}
private $footnotes = [];
}
使用示例
<?php
// 使用示例
require_once 'MarkdownDocumenter.php';
require_once 'AdvancedMarkdownGenerator.php';
// 示例1: 基础文档生成
$docGenerator = new MarkdownDocumenter();
// 从文件生成
$markdown = $docGenerator->generateFromFile('example.php');
$docGenerator->saveToFile('output_documentation.md');
// 或者从源代码生成
$sourceCode = <<<'CODE'
<?php
/**
* 用户类
*/
class User {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
/**
* 示例函数
*/
function hello($name) {
return "Hello, " . $name;
}
CODE;
$markdown = $docGenerator->generateFromSource($sourceCode);
echo $markdown;
// 示例2: 高级文档生成
$advanced = new AdvancedMarkdownGenerator();
$data = [ => 'API 文档',
'description' => '这是API的完整文档说明',
'sections' => [
[
'title' => '概览',
'content' => '这是一个示例API文档...'
],
[
'title' => '安装',
'content' => $advanced->generateCodeBlock('composer install', 'bash')
],
[
'title' => '使用方法',
'content' => '示例代码:'
. $advanced->generateCodeBlock('<?php\n$api = new API();\n$result = $api->call();')
]
]
];
$markdown = $advanced->generate($data);
echo $markdown;
// 示例3: 生成高质量文档
$doc = new AdvancedMarkdownGenerator();
$sections = [
[
'title' => '项目介绍',
'content' => implode("\n", [
'这是一个强大的PHP项目,提供以下功能:',
'',
'```php',
'// 快速开始',
'$instance = new ClassName();',
'$instance->method();',
'```',
])
],
[
'title' => '配置说明',
'content' => $doc->generateTable(
['配置项', '类型', '默认值', '说明'],
[
['debug', 'bool', 'false', '是否开启调试模式'],
['cache', 'bool', 'true', '是否启用缓存'],
['timeout', 'int', '30', '超时时间(秒)'],
]
)
],
[
'title' => 'API 参考',
'content' => implode("\n", [
'### getUser()',
'',
'获取用户信息',
'',
'| 参数 | 类型 | 说明 |',
'|------|------|------|',
'| id | int | 用户ID |',
'',
'**返回值**: array',
'',
'```php',
'$info = $api->getUser(123);',
'```',
])
]
];
$data = [ => '项目文档',
'description' => '自动化生成的完整文档',
'sections' => $sections
];
$markdown = $doc->generate($data);
file_put_contents('project_documentation.md', $markdown);
命令行工具版本
<?php
/**
* markdown-doc.php - 命令行工具
*
* 使用方法:
* php markdown-doc.php <source_file.php> [output_file.md]
*/
require_once 'MarkdownDocumenter.php';
// 检查参数
if ($argc < 2) {
echo "用法: php markdown-doc.php <source_file.php> [output_file.md]\n";
exit(1);
}
$sourceFile = $argv[1];
$outputFile = isset($argv[2]) ? $argv[2] : 'documentation.md';
// 检查文件是否存在
if (!file_exists($sourceFile)) {
echo "错误: 文件 '{$sourceFile}' 不存在\n";
exit(1);
}
// 生成文档
$generator = new MarkdownDocumenter();
$markdown = $generator->generateFromFile($sourceFile);
// 保存文档
if ($generator->saveToFile($outputFile)) {
echo "文档已生成: {$outputFile}\n";
echo "文档大小: " . strlen($markdown) . " bytes\n";
} else {
echo "错误: 无法保存文档\n";
exit(1);
}
高级样式增强
<?php
/**
* StyledMarkdownGenerator - 带样式的Markdown生成器
*/
class StyledMarkdownGenerator extends AdvancedMarkdownGenerator {
/**
* 生成美观的警告框
*
* @param string $type 类型(info, warning, danger, success)
* @param string $message 消息内容
* @return string 警告框Markdown
*/
public function generateAlert($type, $message) {
$icons = [
'info' => 'ℹ️',
'warning' => '⚠️',
'danger' => '🚨',
'success' => '✅'
];
$icon = isset($icons[$type]) ? $icons[$type] : $icons['info'];
return "> {$icon} **" . strtoupper($type) . "**: {$message}";
}
/**
* 生成代码对比
*
* @param string $before 修改前
* @param string $after 修改后
* @return string 对比Markdown
*/
public function generateDiff($before, $after) {
return implode("\n", [
"#### 修改前",
"```php",
$before,
"```",
"",
"#### 修改后",
"```php",
$after,
"```"
]);
}
/**
* 生成扩展的表格(带对齐)
*
* @param array $headers 表头
* @param array $rows 数据
* @param array $alignments 对齐方式
* @return string 对齐表格
*/
public function generateAlignedTable($headers, $rows, $alignments = []) {
$table = "| " . implode(" | ", $headers) . " |\n";
// 对齐标志
$alignmentsSymbols = [
'left' => ':---',
'center' => ':---:',
'right' => '---:'
];
$alignRow = "|";
foreach ($headers as $key => $header) {
$align = isset($alignments[$key]) ? $alignments[$key] : 'left';
$symbol = isset($alignmentsSymbols[$align]) ? $alignmentsSymbols[$align] : ':---';
$alignRow .= " {$symbol} |";
}
$table .= $alignRow . "\n";
foreach ($rows as $row) {
$table .= "| " . implode(" | ", array_map('strval', $row)) . " |\n";
}
return $table;
}
}
这个PHP Markdown文档生成工具提供了完整的解决方案,包括:
- 自动解析:从PHP源代码自动提取类、方法、属性、函数等信息
- 多种格式:支持类、接口、trait、函数等文档生成
- 高级功能:表格、代码块、链接、图片等Markdown元素
- 命令行工具:方便批量处理
- 灵活扩展:支持自定义模板和样式
使用这个工具可以快速生成专业的代码文档,提高开发效率。