
本文介绍如何优化 PHP 下载脚本,通过扩展名(如 .php)统一过滤文件,替代手动列举每个文件名的低效方式,并提供兼容 PHP 7.4+ 的可靠实现方案。
本文介绍如何优化 php 下载脚本,通过扩展名(如 `.php`)统一过滤文件,替代手动列举每个文件名的低效方式,并提供兼容 php 7.4+ 的可靠实现方案。
在构建文件下载列表时,硬编码排除 001.php、002.php 等单个 PHP 文件不仅维护困难,还极易遗漏或出错。正确做法是按文件扩展名进行逻辑过滤——即“隐藏所有 .php 文件”,而非枚举具体文件名。
✅ 推荐方案:使用 str_ends_with()(PHP ≥ 8.0)
PHP 8.0 引入了原生函数 str_ends_with(),语义清晰、性能优秀,是处理扩展名匹配的首选:
function shouldFileBeHidden(string $file): bool {
static $hiddenBasename = ['.access', '.', '.htaccess']; // 需精确匹配的文件名
if (in_array($file, $hiddenBasename, true)) {
return true;
}
// 统一隐藏所有 .php 文件(含 index.php、config.php 等)
if (str_ends_with($file, '.php')) {
return true;
}
return false;
}
// 在 readdir 循环中使用:
while ($file_name = readdir($dir_handle)) {
if (!shouldFileBeHidden($file_name)) {
echo "<a href="download.php?file=%22%20.%20urlencode(%24file_name)%20.%20%22">$file_name</a><br>";
}
}
⚙️ 兼容旧版 PHP(7.4–7.4)的写法
若运行环境为 PHP str_ends_with(无需引入完整 polyfill):
if (!function_exists('str_ends_with')) {
function str_ends_with(string $haystack, string $needle): bool {
if ($needle === '') return true;
$len = strlen($needle);
return strlen($haystack) >= $len
&& substr($haystack, -$len) === $needle;
}
}
随后即可直接调用 str_ends_with($file, '.php'),行为与原生函数完全一致。
? 替代方案:使用 pathinfo()(更通用,稍重)
适用于需同时按多种扩展名(如 .php, .log, .bak)或区分大小写的场景:
function shouldFileBeHidden(string $file): bool {
static $hiddenBasenames = ['.access', '.', '.htaccess'];
static $hiddenExtensions = ['php', 'log', 'tmp']; // 可扩展
if (in_array($file, $hiddenBasenames, true)) {
return true;
}
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
return in_array($ext, $hiddenExtensions, true);
}
⚠️ 注意事项:
- 始终对
$file进行urlencode()处理后再拼入 URL,防止特殊字符(空格、中文、&等)引发安全或解析问题;- 避免依赖
readdir()返回顺序,如需排序请使用scandir()+array_filter();- 生产环境务必校验
$_GET['file']参数,禁止路径遍历(如../../../etc/passwd),建议结合白名单或realpath()+ 目录前缀校验。
通过扩展名驱动的过滤逻辑,你的下载脚本能自动适应新增 PHP 文件,大幅提升可维护性与安全性。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











