如何解决动态生成表格中仅首行文件上传按钮可用的问题?
后台管理页面玩具模型图片上传问题及解决方法
问题背景
正在开发一个后台管理页面,需实现图片上传并关联数据库中的玩具模型对象。页面包含从数据库生成的表格,每行配备删除按钮和上传图片按钮。
原代码实现
原HTML代码
<h3>Toy Models</h3> <br> <div class="toy-table"> <table> <tr> <th>Model ID</th> <th>Name</th> <th>Material</th> <th>Rarity</th> <th> </th> <th> </th> </tr> <?php foreach ($toys as $row): ?> <tr> <td><?= $row['model_id'] ?></td> <td><?= $row['theme'] . ' ' . $row['model_name'] ?></td> <td><?= $row['material']?></td> <td><?= $row['rarity']?></td> <td> <form action="includes/admin-model.inc.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="toyid" value="<?= $row['model_id'] ?>"> <label for="file" class="custom-file"> <input type="file" name="toyfile<?= $row['model_id'] ?>" id="file"> <i class="fa fa-cloud-upload"></i> Upload Image </label> <br> <br> <button type="submit" name="toyimage">SAVE</button> </form> </td> <td> <form action="includes/admin-model.inc.php" method="post"> <input type="hidden" name="toyid" value="<?= $row['model_id'] ?>"> <br> <button type="submit" name="delete">DELETE</button> </form> </td> </tr> <?php endforeach ?> </table> </div>
处理上传的INC PHP代码
else if(isset($_POST['toyimage'])) { $toyID = htmlspecialchars($_POST["toyid"], ENT_QUOTES, 'UTF-8'); $file = $_FILES['toyfile'.$toyID]; // Check for file upload errors if ($file['error'] === UPLOAD_ERR_OK) { $edit = new ModelView(); $edit->editImg($toyID, $file); header("location: ../admin.php?error=none"); } else { // Handle file upload error header("location: ../admin.php?error=upload_failed".$file['error']); } }
后端PHP代码
protected function setImg($tmid, $file){ $fileName = $file['name']; $fileTmpName = $file['tmp_name']; $fileSize = $file['size']; $fileError = $file['error']; $fileType = $file['type']; $fileExt = explode('.', $fileName); $fileActualExt = strtolower(end($fileExt)); $allowed = array('jpg', 'jpeg', 'png'); if (in_array($fileActualExt, $allowed)) { if ($fileError === 0) { if ($fileSize < 1000000) { $fileNameNew = $tmid.".png"; $fileDestination = '../images/toys/'.$fileNameNew; move_uploaded_file($fileTmpName, $fileDestination); } else { echo "Your file is too big!"; } } else { echo "There was an error uploading your file!"; } } else { echo "You cannot upload files of this type!"; } }
问题现象
当前代码仅表格首行的上传按钮可正常工作,后续行使用上传功能时会触发UPLOAD_ERR_NO_FILE(错误码4),文件无法上传。
问题根源及修复方案
问题根源
label的for属性绑定了重复的input ID,导致只有第一个输入框能正确响应点击和文件选择操作,后续行的文件选择无法关联到对应input元素,提交时无文件数据。
修复后的HTML代码
<h3>Toy Models</h3> <br> <div class = "toy-table"> <table> <tr> <th>Model ID</th> <th>Name</th> <th>Material</th> <th>Rarity</th> <th> </th> <th> </th> </tr> <?php foreach ($toys as $row): ?> <tr> <td><?= htmlspecialchars($row['model_id']) ?></td> <td><?= htmlspecialchars($row['theme']) . ' ' . htmlspecialchars($row['model_name']) ?></td> <td><?= htmlspecialchars($row['material'])?></td> <td><?= htmlspecialchars($row['rarity'])?></td> <td> <form action = "includes/admin-model.inc.php" method = "post" enctype="multipart/form-data"> <input type = "hidden" name = "toyid" value = "<?= $row['model_id'] ?>"> <label for = "file_<?= htmlspecialchars($row['model_id']) ?>" class = "custom-file"> <input type="file" name="file" id ="file_<?= htmlspecialchars($row['model_id']) ?>"/> <i class="fa fa-cloud-upload"></i> Upload Image </label> <br> <br> <button type = "submit" name = "toyimage">SAVE</button> </form> </td> <td> <form action = "includes/admin-model.inc.php" method = "post"> <input type = "hidden" name = "toyid" value = "<?= $row['model_id'] ?>"> <br> <button type = "submit" name = "delete">DELETE</button> </form> </td> </tr> <?php endforeach ?> </table> </div>
对应后端调整说明
修复后的HTML中,文件输入框统一命名为file,因此处理上传的INC PHP代码需同步修改,不再通过拼接toyID获取文件:
else if(isset($_POST['toyimage'])) { $toyID = htmlspecialchars($_POST["toyid"], ENT_QUOTES, 'UTF-8'); // 直接获取name为file的文件,不再拼接ID $file = $_FILES['file']; // Check for file upload errors if ($file['error'] === UPLOAD_ERR_OK) { $edit = new ModelView(); $edit->editImg($toyID, $file); header("location: ../admin.php?error=none"); } else { // Handle file upload error header("location: ../admin.php?error=upload_failed".$file['error']); } }
修改后,每行上传按钮可正常关联对应文件输入框,提交时正确传递文件数据,解决仅首行可上传的问题。
内容的提问来源于stack exchange,提问作者Simon Audrey
相关产品推荐
相关产品推荐

