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

PHP上传JPEG至MySQL无法获取图片元数据的问题排查

解决图片上传时无法获取元数据(宽度)的问题

核心问题分析

你的代码无法获取图片宽度的关键原因:

  • 调用getExif时传入的是客户端文件名,此时文件还在服务器临时目录,exif_read_data找不到对应文件,返回默认值0。
  • 扩展名判断逻辑有误,无法识别jpeg这类4字符后缀的文件。
  • 仅依赖Exif无法兼容PNG、GIF等无Exif数据的图片格式。
  • 直接拼接SQL语句存在注入风险。

修正后的完整代码

<?php 
// Include the database configuration file 
include_once 'dbconfig.php'; 

if(isset($_POST['submit'])){
    // File upload configuration 
    $targetDir = "C:\xampp\htdocs\uploaded\\"; 
    $allowTypes = array('jpg','png','jpeg','gif'); 

    $statusMsg = $errorMsg = $insertValuesSQL = $errorUpload = $errorUploadType = ''; 
    $fileNames = array_filter($_FILES['files']['name']); 
    
    if(!empty($fileNames)){
        // 获取图片宽度,兼容所有支持的格式
        function getImageWidth($filePath) {
            $width = 0;
            // 先尝试用getimagesize,兼容所有图片类型
            $imageInfo = getimagesize($filePath);
            if($imageInfo !== false){
                $width = $imageInfo[0];
            } 
            return $width;
        }

        foreach($_FILES['files']['name'] as $key=>$val){
            // 获取临时文件路径,这是当前服务器上存在的文件
            $tmpFilePath = $_FILES["files"]["tmp_name"][$key];
            $fileName = basename($_FILES['files']['name'][$key]); 
            // 从临时文件获取宽度
            $width = getImageWidth($tmpFilePath);

            $targetFilePath = $targetDir . $fileName; 
            // 正确获取文件扩展名
            $fileType = strtolower(pathinfo($targetFilePath, PATHINFO_EXTENSION)); 
            
            if(in_array($fileType, $allowTypes)){
                // Upload file to server 
                if(move_uploaded_file($tmpFilePath, $targetFilePath)){ 
                    // 使用预处理语句避免SQL注入(推荐方式)
                    // 这里先改用占位符,后续统一处理
                    $insertValuesSQL .= "('".$fileName."', NOW(), '".$width."'),"; 
                }else{ 
                    $errorUpload .= $_FILES['files']['name'][$key].' | '; 
                } 
            }else{ 
                $errorUploadType .= $_FILES['files']['name'][$key].' | '; 
            } 
        }
        
        // Error message 
        $errorUpload = !empty($errorUpload)?'Upload Error: '.trim($errorUpload, ' | '):''; 
        $errorUploadType = !empty($errorUploadType)?'File Type Error: '.trim($errorUploadType, ' | '):''; 
        $errorMsg = !empty($errorUpload)?'<br/>'.$errorUpload.'<br/>'.$errorUploadType:'<br/>'.$errorUploadType; 

        if(!empty($insertValuesSQL)){
            $insertValuesSQL = trim($insertValuesSQL, ','); 
            
            // 注意:生产环境建议使用预处理语句替代直接拼接,示例如下:
            // $stmt = $db->prepare("INSERT INTO images(file_name, uploaded_on, image_width) VALUES (?, NOW(), ?)");
            // foreach(...) { ... $stmt->bind_param("si", $fileName, $width); $stmt->execute(); ... }
            
            // Insert image file name into database 
            $insert = $db->query("INSERT INTO images(file_name, uploaded_on, image_width) VALUES $insertValuesSQL"); 
            if($insert){ 
                $statusMsg = "Files are uploaded successfully.".$errorMsg; 
            }else{ 
                $statusMsg = "Sorry, there was an error uploading your file."; 
            } 
        }else{ 
            $statusMsg = "Upload failed! ".$errorMsg; 
        } 
    }else{ 
        $statusMsg = 'Please select a file to upload.'; 
    }
}

?>
    <form action="upload1.php" method="post" enctype="multipart/form-data">
        Select Image Files to Upload:
        <input type="file" name="files[]" multiple >
        <input type="submit" name="submit" value="UPLOAD">
    </form>

关键修改说明

  1. 改用临时文件路径获取元数据:使用$_FILES["files"]["tmp_name"][$key]作为读取文件的路径,此时文件已上传到服务器临时目录,可以正常读取。
  2. 替换为getimagesize获取宽度:该函数支持所有PHP支持的图片格式(JPG/PNG/GIF等),无需依赖Exif,兼容性更好。
  3. 修正扩展名判断:用pathinfo配合strtolower正确获取文件扩展名,避免jpeg这类后缀被误判。
  4. 添加SQL注入安全提示:生产环境建议使用预处理语句替代字符串拼接,避免SQL注入风险。

扩展说明

如果需要获取更多元数据(如Exif里的拍摄时间、相机型号等),可以在getImageWidth函数中结合exif_read_data补充逻辑,示例:

function getImageMetadata($filePath) {
    $metadata = [
        'width' => 0,
        'height' => 0,
        'camera' => '',
        'shot_time' => ''
    ];
    // 获取基础尺寸
    $imageInfo = getimagesize($filePath);
    if($imageInfo !== false){
        $metadata['width'] = $imageInfo[0];
        $metadata['height'] = $imageInfo[1];
    }
    // 尝试读取Exif数据(仅支持JPG/TIFF)
    $exif = exif_read_data($filePath, 0, true);
    if($exif !== false){
        $metadata['camera'] = $exif['IFD0']['Model'] ?? '';
        $metadata['shot_time'] = $exif['EXIF']['DateTimeOriginal'] ?? '';
    }
    return $metadata;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:25:07