PHP多文件上传失败求助:含缩略图生成与重命名,需保留4个input
Let's break down the problems in your code and fix them step by step:
1. Invalid HTML: Duplicate IDs
All four file inputs share the same ID upload-image-three. IDs must be unique in HTML—this can break your readURL function and cause unexpected behavior. Update each input to have a unique ID:
<input type="file" name="files[]" id="upload-image-1" onchange="readURL(this);"> <input type="file" name="files[]" id="upload-image-2" onchange="readURL(this);"> <input type="file" name="files[]" id="upload-image-3" onchange="readURL(this);"> <input type="file" name="files[]" id="upload-image-4" onchange="readURL(this);">
2. Incorrect File Size Validation
Your code checks for files larger than 2000 MB instead of 2 MB. Fix the size limit:
// 2 MB = 2 * 1024 * 1024 = 2097152 bytes if ($file_size > 2097152) { $errors[] = 'File size must be less than 2 MB'; }
3. Missing Upload Error Handling
You’re not checking for built-in PHP upload errors, which are critical for diagnosing failures. Add this check inside your file loop:
$file_error = $_FILES['files']['error'][$key]; if ($file_error !== UPLOAD_ERR_OK) { switch ($file_error) { case UPLOAD_ERR_INI_SIZE: $errors[] = 'File exceeds php.ini upload limit'; break; case UPLOAD_ERR_FORM_SIZE: $errors[] = 'File exceeds form upload limit'; break; case UPLOAD_ERR_PARTIAL: $errors[] = 'File was only partially uploaded'; break; case UPLOAD_ERR_NO_FILE: $errors[] = 'No file was selected for upload'; break; case UPLOAD_ERR_CANT_WRITE: $errors[] = 'Failed to write file to disk (permission issue?)'; break; default: $errors[] = 'Unknown upload error occurred'; } }
4. Permission & Directory Issues
Ensure your upload/ and thumb/ directories:
- Exist (your code creates
upload/but notthumb/—addmkdir("thumb/", 0755);if needed) - Are writable by the web server user (set permissions to
755or adjust ownership to match your server’s user, e.g.,www-data)
5. Thumbnail Generation Inefficiency
Your current code regenerates thumbnails for every image in upload/ on every submission. Instead, generate thumbnails immediately after uploading each new file:
// After move_uploaded_file succeeds: $source = $desired_dir . $file_name . $sExt; $dest = "thumb/" . $file_name . $sExt; generateThumbnail($source, $dest, 100, 100); // Add this helper function outside your loop: function generateThumbnail($source, $dest, $nw, $nh) { $size = getimagesize($source); $w = $size[0]; $h = $size[1]; $stype = explode(".", $source); $stype = strtolower(end($stype)); switch ($stype) { case 'gif': $simg = imagecreatefromgif($source); break; case 'jpg': $simg = imagecreatefromjpeg($source); break; case 'png': $simg = imagecreatefrompng($source); break; default: return false; } $dimg = resizePreservingAspectRatio($simg, $nw, $nh); imagepng($dimg, $dest); imagedestroy($simg); imagedestroy($dimg); return true; }
6. Unsafe & Unnecessary eval() Usage
Creating variables like $file1 with eval() is risky and unnecessary. Use an array instead:
$uploadedFiles = []; // After successful upload: $uploadedFiles[] = $file_name . $sExt; // Later, use $uploadedFiles[0], $uploadedFiles[1], etc., in your database query
7. Incomplete Code Fix
Your provided code cuts off mid-database insert. Ensure all form fields are properly closed in your execute() call, e.g.:
$stmt->execute(array( ':title' => filter_input(INPUT_POST, 'title'), ':brand' => filter_input(INPUT_POST, 'brand'), ':model' => filter_input(INPUT_POST, 'model'), ':kmdriven' => filter_input(INPUT_POST, 'kmdriven'), ':price' => filter_input(INPUT_POST, 'price'), ':nego' => filter_input(INPUT_POST, 'nego'), ':year' => filter_input(INPUT_POST, 'year'), ':addes' => filter_input(INPUT_POST, 'addes'), ':sname' => filter_input(INPUT_POST, 'sname'), ':smail' => filter_input(INPUT_POST, 'smail'), ':sphone' => filter_input(INPUT_POST, 'sphone') ));
Final Notes
- Always validate file types using server-side checks (don’t rely solely on client-side MIME types). Use
finfo_fileto detect actual file content for better security. - Enable PHP error reporting (
error_reporting(E_ALL); ini_set('display_errors', 1);) temporarily to see any hidden errors during testing.
内容的提问来源于stack exchange,提问作者sanoj lawrence

