如何让PHP文件管理器实现递归访问,无需在各目录放置index文件
实现单文件PHP目录浏览器
问题
我正在用PHP开发一款文件资源管理器,现在得在每个文件夹里都放个index.php才能访问对应目录。怎么实现动态/递归功能,只用单个index.php就能访问所有目录?
原代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>M07</title> </head> <body> <?php $contingut = ""; if($handle = opendir('.')){ while (false !== ($file = readdir($handle))){ if (($file != ".") && ($file != "..") && ($file != "index.php") && ($file != "desktop.ini")){ $contingut .= '<a id="enllaç" href="'.$file.'">'.$file.'</a><br><br>'; } } closedir($handle); } ?> <?php echo $contingut ?>
解决方案
核心是通过URL参数传递当前访问目录,用单个index.php处理所有请求,无需在每个目录放置文件。以下是修改后的实现:
1. 安全的动态目录处理代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文件资源管理器</title> <style> .file-item { margin: 8px 0; } .folder { color: #2c3e50; font-weight: bold; } .back-btn { margin-bottom: 16px; padding: 4px 8px; } </style> </head> <body> <?php // 定义允许访问的根目录(必须是绝对路径,防止目录遍历) $rootDir = __DIR__; // 获取用户请求的目录,默认是根目录 $currentDir = isset($_GET['dir']) ? $_GET['dir'] : ''; // 安全校验:防止目录遍历漏洞,确保请求的目录在根目录范围内 $targetDir = realpath($rootDir . DIRECTORY_SEPARATOR . $currentDir); if (!$targetDir || strpos($targetDir, $rootDir) !== 0) { die('非法访问:禁止访问该目录'); } $content = ''; // 添加返回上一级按钮(如果不在根目录) if ($targetDir !== $rootDir) { $parentDir = dirname($currentDir); $content .= '<a href="?dir=' . urlencode($parentDir) . '" class="back-btn">← 返回上一级</a><br>'; } // 遍历当前目录 if ($handle = opendir($targetDir)) { while (false !== ($file = readdir($handle))) { if ($file === "." || $file === ".." || $file === "desktop.ini") { continue; } $filePath = $targetDir . DIRECTORY_SEPARATOR . $file; $relativePath = $currentDir ? $currentDir . DIRECTORY_SEPARATOR . $file : $file; $url = is_dir($filePath) ? '?dir=' . urlencode($relativePath) : $relativePath; // 区分文件夹和文件的样式 $class = is_dir($filePath) ? 'folder' : 'file'; $content .= '<div class="file-item"><a href="' . htmlspecialchars($url) . '" class="' . $class . '">' . htmlspecialchars($file) . '</a></div>'; } closedir($handle); } else { $content .= '<p>无法访问该目录</p>'; } ?> <?php echo $content ?> </body> </html>
2. 关键改进点
- 目录安全控制:用
realpath()和字符串校验确保用户只能访问$rootDir范围内的目录,彻底防范目录遍历攻击(比如?dir=../../etc这类恶意请求) - 动态目录传递:通过
?dir=xxx参数传递当前访问的目录路径,点击文件夹时自动拼接该参数 - 用户体验优化:添加返回上一级按钮,区分文件夹和文件样式
- 安全输出:用
htmlspecialchars()转义输出内容,防止XSS攻击
3. 服务器配置(可选,优化URL美观度)
如果想让URL更友好(比如/files/docs而不是/?dir=docs),可以配置服务器重写规则:
Apache(.htaccess)
在根目录创建.htaccess文件:
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?dir=$1 [QSA,L]
Nginx
在站点配置中添加:
location / { try_files $uri $uri/ /index.php?dir=$uri; }
注意事项
- 确保PHP进程对目标目录有读取权限,否则无法遍历文件
- 不要随意放开
$rootDir范围,严格限制可访问的目录 - 可以根据需求添加文件下载、排序、搜索等扩展功能
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

