电商产品编辑功能异常求助:非图片修改无法保存
Hey there, let's break down what's going wrong here and fix it step by step!
First, let's identify the core problems in your code that are causing the "changes only save when re-uploading images" issue:
1. Unconditional Image Field Update
Your current UPDATE statement always overwrites the image field with $dbpath, even when the user doesn't upload a new image. If $dbpath isn't populated with the existing product's image path when no new upload happens, this will either erase the existing image path (setting it to an empty value) or cause the entire update to fail if the image column is set to NOT NULL. This is why changes only stick when you re-upload an image—because that's the only time $dbpath has a valid value.
2. Critical SQL Injection Vulnerability
You're directly inserting user-controlled variables into your SQL query, which is a huge security risk. Attackers could easily manipulate values like $title or $edit_id to alter or delete your database data.
3. Query Execution Outside the Conditional
Your mysqli_query call sits outside the if(isset($_GET['edit'])) block. If $_GET['edit'] isn't set, $query won't be defined at all, leading to a silent error that might break your code without you noticing.
Here's the Fixed, Secure Code
Let's rewrite this to handle image updates properly, fix security gaps, and ensure reliable saves every time:
if(isset($_GET['edit'])) { // Initialize arrays to build our dynamic update query $updateFields = []; $params = []; $paramTypes = ""; // Add core product fields (we always want to update these) $updateFields[] = "title = ?"; $params[] = $title; $paramTypes .= "s"; // 's' for string type $updateFields[] = "price = ?"; $params[] = $price; $paramTypes .= "d"; // 'd' for decimal/number (use 's' if price is stored as string) $updateFields[] = "description = ?"; $params[] = $desc; $paramTypes .= "s"; $updateFields[] = "category = ?"; $params[] = $cat; $paramTypes .= "s"; // Only update the image field if a NEW image was uploaded // Replace this condition with your actual file upload validation (use $_FILES checks for accuracy) if(isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK && !empty($dbpath)) { $updateFields[] = "image = ?"; $params[] = $dbpath; $paramTypes .= "s"; } // Add the product ID for the WHERE clause $params[] = $edit_id; $paramTypes .= "i"; // 'i' for integer type (assuming edit_id is a number) // Build the final SQL query $query = "UPDATE products SET " . implode(", ", $updateFields) . " WHERE id = ?"; // Use prepared statements to eliminate SQL injection $stmt = mysqli_prepare($db, $query); mysqli_stmt_bind_param($stmt, $paramTypes, ...$params); mysqli_stmt_execute($stmt); // Check if the update was successful if(mysqli_stmt_affected_rows($stmt) > 0) { echo "Product updated successfully!"; } else { echo "No changes made, or update failed: " . mysqli_error($db); } mysqli_stmt_close($stmt); }
Key Improvements Explained
- Dynamic Update Logic: We only include the
imagefield in the update if a valid new image was uploaded. This preserves the existing image path when the user doesn't upload a replacement. - Prepared Statements: Separates SQL structure from user input to completely eliminate SQL injection risks.
- Conditional Execution: The entire update process lives inside the
if(isset($_GET['edit']))block, so we never run an undefined query. - Error Feedback: Added checks for affected rows and error messages to help debug any remaining issues quickly.
Quick Additional Tips
- Double-check your file upload code: Make sure
$dbpathis only set when a valid file is uploaded. If no file is selected, leave it unset or empty. - Validate all user input before updating the database (e.g., ensure
$titleisn't empty,$priceis a valid number). - Enable error reporting during development to catch issues early:
error_reporting(E_ALL); ini_set('display_errors', 1);
内容的提问来源于stack exchange,提问作者Javiera Del Escoval

