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

PHP文件上传报错:move_uploaded_file提示访问null数组偏移量

解决PHP文件上传报错:Trying to access array offset on value of type null

问题根源

从你提供的var_dump($_FILES)输出可以看到:

array(1) { 
    ["file"]=> array(6) { 
        ["name"]=> string(11) "MotoGP.pptx" 
        ["full_path"]=> string(11) "MotoGP.pptx" 
        ["type"]=> string(0) "" 
        ["tmp_name"]=> string(0) "" 
        ["error"]=> int(1) 
        ["size"]=> int(0) 
    } 
}

其中error字段值为1,对应PHP内置常量UPLOAD_ERR_INI_SIZE,说明该pptx文件的大小超过了PHP配置中设置的上传文件大小限制,导致服务器没有生成临时文件,tmp_name因此为空,后续调用move_uploaded_file时触发数组偏移访问错误。

解决步骤

1. 调整PHP上传配置

找到服务器上的php.ini配置文件,修改以下参数:

  • upload_max_filesize:设置为大于你要上传的最大文件大小,例如:upload_max_filesize = 20M
  • post_max_size:该值必须大于upload_max_filesize,例如:post_max_size = 25M
    修改完成后,重启你的Web服务器(Apache/Nginx)使配置生效。

2. 完善代码的错误检查逻辑

在处理文件上传前,先检查上传错误状态,避免无效的后续操作。修改后的函数如下:

function dodajTorrent($kategorije) {
    if (isset($_POST['gumb'])) {
        $link = open_database_connection();
        $vseKategorije = serialize($kategorije);
        $naslov = $_POST['naslov'];
        $vsebina = $_POST['vsebina'];
        $kategorija = $_POST['kategorija'];
        $file = $_FILES['file'];

        // 第一步:检查文件上传错误
        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMessages = [
                UPLOAD_ERR_INI_SIZE => '文件大小超过服务器限制',
                UPLOAD_ERR_FORM_SIZE => '文件大小超过表单限制',
                UPLOAD_ERR_PARTIAL => '文件仅部分上传',
                UPLOAD_ERR_NO_FILE => '未选择文件',
                UPLOAD_ERR_NO_TMP_DIR => '服务器缺少临时文件夹',
                UPLOAD_ERR_CANT_WRITE => '无法写入临时文件',
                UPLOAD_ERR_EXTENSION => 'PHP扩展阻止了文件上传'
            ];
            $errorMsg = isset($errorMessages[$file['error']]) ? $errorMessages[$file['error']] : '未知上传错误';
            echo '<script type="text/javascript"> alert("上传错误: ' . $errorMsg . '") </script>';
            mysqli_close($link);
            return;
        }

        $filename = $file['name'];
        $extention = pathinfo($filename, PATHINFO_EXTENSION);

        if (empty($naslov) || empty($vsebina) || $kategorija == 0) {
            echo '<script type="text/javascript"> alert("You left empty fields!") </script>';
        } else {
            // 优化文件扩展名检查
            $allowedExts = ["torrent", "docx", "doc", "rtf", "xls", "xlsx", "ppt", "pptx", "pdf", "7z", "zip", "rar"];
            if (!in_array(strtolower($extention), $allowedExts)) {
                echo '<script type="text/javascript"> alert("Error uploading file: ' . $extention . '") </script>';
            } else {
                // 预处理语句避免SQL注入
                $sql = "SELECT NASLOV FROM Torrenti WHERE NASLOV = ?";
                $stmt = mysqli_prepare($link, $sql);
                mysqli_stmt_bind_param($stmt, "s", $naslov);
                mysqli_stmt_execute($stmt);
                mysqli_stmt_store_result($stmt);
                $st_vrstic = mysqli_stmt_num_rows($stmt);
                mysqli_stmt_close($stmt);

                if ($st_vrstic == 1) {
                    echo '<script type="text/javascript"> alert("Torrent already exists!") </script>';
                } else {
                    $torrentDatoteka = str_replace(' ', '_', $filename);
                    $file123 = "files/" . $torrentDatoteka;
                    $fileFullPath = "/var/www/html/torrent-tracker/files/" . $torrentDatoteka;

                    if (file_exists($fileFullPath)) {
                        echo '<script type="text/javascript"> alert("File already exists!") </script>';
                    } else {
                        $username = $_SESSION['uporabnik'];
                        // 预处理语句获取用户ID
                        $sql = "SELECT ID FROM Blinker_IP WHERE UPORABNIK=?";
                        $stmt = mysqli_prepare($link, $sql);
                        mysqli_stmt_bind_param($stmt, "s", $username);
                        mysqli_stmt_execute($stmt);
                        $vrstica = mysqli_fetch_row($stmt);
                        $id_uporabnika = $vrstica[0];
                        mysqli_stmt_close($stmt);

                        $path = "/var/www/html/torrent-tracker/files";
                        $tmp_name = $file['tmp_name'];
                        $name = basename($torrentDatoteka);

                        $sqlID = "SELECT MAX(ID) FROM Torrenti";
                        $rezultat = mysqli_query($link, $sqlID);
                        $vrstica = mysqli_fetch_row($rezultat);
                        $IdNovegaTorrenta = $vrstica[0] + 1;

                        $vsebinaPoti = "VsebineTorrentov/" . $IdNovegaTorrenta . ".txt";
                        file_put_contents($vsebinaPoti, $_POST['vsebina']);

                        if (move_uploaded_file($tmp_name, "$path/$name")) {
                            echo "File moved successfully";
                        } else {
                            echo "File move failed: " . error_get_last()["message"] . "<br>";
                        }

                        // 预处理语句插入数据
                        $sql = "INSERT INTO Torrenti (NASLOV, VSEBINA, ID_UP, DATOTEKA, KATEGORIJA, ŽANR) VALUES (?, ?, ?, ?, ?, ?)";
                        $stmt = mysqli_prepare($link, $sql);
                        mysqli_stmt_bind_param($stmt, "ssisss", $naslov, $vsebinaPoti, $id_uporabnika, $file123, $kategorija, $vseKategorije);
                        mysqli_stmt_execute($stmt);
                        mysqli_stmt_close($stmt);

                        $location = (vrniRang() == 1) ? "index.php?stran=admin_main" : "index.php?stran=mod_main";
                        mysqli_close($link);
                        header("Location: " . $location);
                        exit;
                    }
                }
            }
        }
    }
}

3. 其他关键修复点

  • SQL注入防护:原代码直接拼接用户输入到SQL语句,存在严重安全风险,修改后使用mysqli预处理语句绑定参数,彻底避免注入问题。
  • 扩展名检查优化:用in_array+strtolower统一扩展名大小写,避免因大小写差异导致的上传拒绝。
  • 资源泄漏修复:在函数终止前关闭数据库连接,避免资源浪费。
  • 逻辑简化:移除重复的$st_vrstic == 0判断,精简代码流程。
  • 表单验证:确保HTML表单添加enctype="multipart/form-data"属性,否则文件无法正常上传。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:39:54