You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP上传程序中重命名指定类型的文件扩展名?

问题原因排查
  • 当检测到文件后缀为sh时,你仅更新了$newFileName变量为.txt后缀,没有同步更新保存文件用的$fileUploadPath变量。$fileUploadPath还是用最开始生成的带.sh后缀的路径值,所以move_uploaded_file实际把文件存成了随机名.sh,你跳转的地址是随机名.txt,自然找不到对应文件,看起来就像没有上传成功。
  • 执行header()跳转后没有添加exit()/die()终止代码执行,可能导致后续逻辑异常。
  • 目前代码仅处理了后缀属于$notAllowed的文件,其余后缀的文件没有任何上传逻辑,也没有错误提示。
  • 路径拼接需要注意/uploads/的开头斜杠是否和getcwd()返回的路径匹配,避免出现路径拼接错误。
修复方案

下面是修复后的完整代码:

$fileName = $_FILES["file"]["name"];
$fileSize = $_FILES["file"]["size"];
$fileExt = explode(".", $fileName);
$fileRealExt = strtolower(end($fileExt));
$uploadDirectory = "/uploads/";
$currentDirectory = getcwd();
$fileTmpName = $_FILES["file"]["tmp_name"];
$notAllowed = array("sh");

if (isset($_POST["submit"])) {
    // 先判断上传是否有系统级错误
    if ($_FILES["file"]["error"] !== UPLOAD_ERR_OK) {
        header("Location: error.php");
        exit();
    }
    // 统一生成最终文件名
    if (in_array($fileRealExt, $notAllowed)) {
        $newFileName = uniqid("", true)  . ".txt";
    } else {
        $newFileName = uniqid("", true)  . "." . $fileRealExt;
    }
    // 统一生成上传路径,避免变量不同步
    $fileUploadPath = $currentDirectory . $uploadDirectory . $newFileName;
    // 提前检查上传目录是否存在、是否有写入权限
    if (!is_dir($currentDirectory . $uploadDirectory) || !is_writable($currentDirectory . $uploadDirectory)) {
        header("Location: error.php");
        exit();
    }
    $didUpload = move_uploaded_file($fileTmpName, $fileUploadPath);
    if ($didUpload) {
        header("Location: $uploadDirectory$newFileName");
        exit();
    } else{
        header("Location: error.php");
        exit();
    }
}
?>
额外优化建议
  • 可以在修改sh后缀为txt的同时,对文件内容做安全校验,避免恶意代码伪装成其他格式上传。
  • 可以限制上传文件的大小,避免服务器存储被占满。
  • 原代码中$fileName = $fileExt[0] . ".txt";没有实际使用,可以删除,或者如果需要保留原文件名前缀,可以把uniqid和原文件名结合使用。

内容的提问来源于stack exchange,提问作者Funnydog204

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:18:01