如何实现无高度参数的图片上传与缩放(限960px宽)并更新数据库?
Alright, let's build out that image upload feature you need—supporting JPG/PNG/GIF, auto-resizing to max 960px width, and saving everything to your database. Here's a complete, tested solution broken down step by step:
1. Frontend Setup
First, let's make the hidden file input usable with a trigger button, plus optional image preview for better UX:
<!-- Hidden file input (restricted to allowed image types) --> <input type='file' id='inpfile' accept="image/jpeg, image/png, image/gif" hidden> <!-- Visible button to trigger file selection --> <button onclick="document.getElementById('inpfile').click()">Select Image</button> <!-- Optional: Preview selected image before upload --> <div id="preview-container" style="margin-top: 10px; max-width: 300px;"></div> <script> document.getElementById('inpfile').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; // Show image preview const reader = new FileReader(); reader.onload = function(event) { const img = document.createElement('img'); img.src = event.target.result; img.style.maxWidth = '100%'; document.getElementById('preview-container').innerHTML = ''; document.getElementById('preview-container').appendChild(img); }; reader.readAsDataURL(file); // Submit file via AJAX (alternatively, use a traditional form) const formData = new FormData(); formData.append('inpfile', file); fetch('upload.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { alert('Image uploaded and processed successfully!'); } else { alert('Oops, something went wrong: ' + data.message); } }) .catch(error => console.error('Upload error:', error)); }); </script>
2. Backend PHP Processing (upload.php)
Let's complete and enhance your existing code to handle validation, resizing, saving, and database updates:
<?php // Enable debugging (disable in production) error_reporting(E_ALL); ini_set('display_errors', 1); // Database credentials (replace with your own) $dbHost = 'localhost'; $dbUser = 'your_db_user'; $dbPass = 'your_db_pass'; $dbName = 'your_db_name'; // Connect to database $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName); if ($conn->connect_error) { die(json_encode(['success' => false, 'message' => 'Database connection failed: ' . $conn->connect_error])); } // Check if file was uploaded correctly if (!isset($_FILES['inpfile']) || $_FILES['inpfile']['error'] !== UPLOAD_ERR_OK) { echo json_encode(['success' => false, 'message' => 'No file uploaded or upload error occurred']); exit; } $file = $_FILES['inpfile']; $filename = $file['name']; $tempname = $file['tmp_name']; $filesize = $file['size']; // Validate file type using MIME (more reliable than extension) $allowedMimes = ['image/jpeg', 'image/png', 'image/gif']; $info = getimagesize($tempname); $mime = $info['mime']; if (!in_array($mime, $allowedMimes)) { echo json_encode(['success' => false, 'message' => 'Invalid file type. Only JPG, PNG, GIF are allowed.']); exit; } // Optional: Add file size limit (e.g., 5MB) if ($filesize > 5 * 1024 * 1024) { echo json_encode(['success' => false, 'message' => 'File too large. Max size is 5MB.']); exit; } // Calculate resized dimensions (maintain aspect ratio, max width 960px) $origw = $info[0]; $origh = $info[1]; $maxWidth = 960; $neww = $origw; $newh = $origh; if ($origw > $maxWidth) { $neww = $maxWidth; $newh = ($origh / $origw) * $maxWidth; } // Create image resource based on MIME type switch ($mime) { case 'image/jpeg': $srcImg = imagecreatefromjpeg($tempname); break; case 'image/png': $srcImg = imagecreatefrompng($tempname); // Preserve transparency for PNGs imagealphablending($srcImg, true); imagesavealpha($srcImg, true); break; case 'image/gif': $srcImg = imagecreatefromgif($tempname); break; default: echo json_encode(['success' => false, 'message' => 'Unsupported image type']); exit; } // Create new blank image for resizing $destImg = imagecreatetruecolor($neww, $newh); // Handle transparency for PNG/GIF if ($mime === 'image/png' || $mime === 'image/gif') { imagealphablending($destImg, false); imagesavealpha($destImg, true); $transparent = imagecolorallocatealpha($destImg, 255, 255, 255, 127); imagefill($destImg, 0, 0, $transparent); } // Resize the image (high quality resampling) imagecopyresampled($destImg, $srcImg, 0, 0, 0, 0, $neww, $newh, $origw, $origh); // Generate unique filename to avoid conflicts $newFilename = uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION); $uploadDir = 'uploads/'; // Create upload directory if it doesn't exist if (!file_exists($uploadDir)) { mkdir($uploadDir, 0755, true); } $filePath = $uploadDir . $newFilename; // Save resized image switch ($mime) { case 'image/jpeg': imagejpeg($destImg, $filePath, 85); // 85% quality balances size and clarity break; case 'image/png': imagepng($destImg, $filePath); break; case 'image/gif': imagegif($destImg, $filePath); break; } // Free up memory imagedestroy($srcImg); imagedestroy($destImg); // Update database (example table structure) $originalName = $conn->real_escape_string($filename); $filePathEscaped = $conn->real_escape_string($filePath); $uploadDate = date('Y-m-d H:i:s'); // Use prepared statements for better security (recommended) $stmt = $conn->prepare("INSERT INTO images (file_path, original_name, upload_date) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $filePathEscaped, $originalName, $uploadDate); if ($stmt->execute()) { echo json_encode([ 'success' => true, 'message' => 'Image uploaded and saved to database', 'image_id' => $stmt->insert_id ]); } else { // Clean up uploaded file if database fails unlink($filePath); echo json_encode(['success' => false, 'message' => 'Database update failed: ' . $stmt->error]); } // Cleanup $stmt->close(); $conn->close(); ?>
3. Critical Setup Notes
- Directory Permissions: Make sure the
uploads/directory has write permissions (set to0755or0775depending on your server). - Security: Always use prepared statements for database queries (as shown) to prevent SQL injection. Avoid relying solely on file extensions for validation.
- GIF Animations: The above code will resize GIFs but lose animation. If you need to preserve animations, use a library like ImageMagick or a dedicated GIF processing package.
内容的提问来源于stack exchange,提问作者qadenza
相关产品推荐
相关产品推荐

