基于PDO获取的数据库数组构建可编辑表单并提交修改的需求
嘿,你已经迈出了从数据库拉取数据的关键一步!接下来咱们把这些数据变成可编辑的表单,再把修改后的内容安全地提交回数据库,我给你一步步梳理实现方案:
1. 完善数据获取逻辑(增加错误处理)
你的现有代码已经能拿到数据,但生产环境里最好加上异常捕获,避免因为数据库连接或存储过程调用失败导致白屏:
<?php $printable = []; try { $db = new PDO('mysql:host=mariadb.spectrogon.local;dbname=gitter;charset=utf8', 'gitter_in', 'gitter_in'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开启异常模式 $sql = "call hämta_artikel_info('715.702.930')"; $result = $db->query($sql); $printable = $result->fetchAll(PDO::FETCH_ASSOC); // 用关联数组更方便渲染表单 } catch(PDOException $e) { echo "数据库错误: " . $e->getMessage(); exit; } ?>
2. 渲染可编辑表单
假设$printable里的每条数据是一个关联数组(比如包含artikel_nr、namn、beskrivning等字段),咱们把这些字段转换成表单输入框,默认填充从数据库拿到的值:
<!-- 表单提交到当前页面,用POST方法 --> <form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>"> <!-- 隐藏主键,用于后续更新定位数据 --> <?php if(!empty($printable)): ?> <?php foreach($printable as $index => $item): ?> <!-- 每条数据的表单区域,如果是单条数据可以去掉循环 --> <div class="artikel-form"> <h3>商品信息 #<?php echo $index + 1; ?></h3> <!-- 隐藏主键,比如artikel_nr --> <input type="hidden" name="artiklar[<?php echo $index; ?>][artikel_nr]" value="<?php echo htmlspecialchars($item['artikel_nr']); ?>"> <!-- 商品名称输入框 --> <div> <label for="namn_<?php echo $index; ?>">商品名称:</label> <input type="text" id="namn_<?php echo $index; ?>" name="artiklar[<?php echo $index; ?>][namn]" value="<?php echo htmlspecialchars($item['namn']); ?>" required> </div> <!-- 商品描述文本域 --> <div> <label for="beskrivning_<?php echo $index; ?>">商品描述:</label> <textarea id="beskrivning_<?php echo $index; ?>" name="artiklar[<?php echo $index; ?>][beskrivning]" rows="4"><?php echo htmlspecialchars($item['beskrivning']); ?></textarea> </div> <!-- 其他字段同理,根据你的数据库字段添加 --> <div> <label for="pris_<?php echo $index; ?>">价格:</label> <input type="number" step="0.01" id="pris_<?php echo $index; ?>" name="artiklar[<?php echo $index; ?>][pris]" value="<?php echo htmlspecialchars($item['pris']); ?>"> </div> </div> <?php endforeach; ?> <!-- 提交按钮 --> <button type="submit" name="submit_update">保存修改</button> <?php else: ?> <p>未找到商品信息</p> <?php endif; ?> </form>
注意:用htmlspecialchars()转义输出值,能防止XSS攻击,这是前端渲染的安全必备操作。
3. 处理表单提交(更新数据库)
当用户点击“保存修改”按钮后,咱们需要接收POST数据,用PDO预处理语句安全地更新数据库(避免SQL注入)。这里假设你有一个用于更新的存储过程uppdatera_artikel_info,参数对应各个字段:
<?php // 处理表单提交 if(isset($_POST['submit_update']) && !empty($_POST['artiklar'])) { try { // 重新连接数据库(或者复用之前的$db连接,如果没销毁的话) $db = new PDO('mysql:host=mariadb.spectrogon.local;dbname=gitter;charset=utf8', 'gitter_in', 'gitter_in'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 准备更新的存储过程调用语句 $updateSql = "call uppdatera_artikel_info(:artikel_nr, :namn, :beskrivning, :pris)"; $stmt = $db->prepare($updateSql); // 循环处理每条提交的数据 foreach($_POST['artiklar'] as $artikel) { // 绑定参数 $stmt->bindParam(':artikel_nr', $artikel['artikel_nr'], PDO::PARAM_STR); $stmt->bindParam(':namn', $artikel['namn'], PDO::PARAM_STR); $stmt->bindParam(':beskrivning', $artikel['beskrivning'], PDO::PARAM_STR); $stmt->bindParam(':pris', $artikel['pris'], PDO::PARAM_STR); // 如果是数字类型可以用PARAM_INT // 执行更新 $stmt->execute(); } echo "<p>所有商品信息已成功更新!</p>"; // 可以在这里刷新页面或者跳转到列表页 // header("Location: " . $_SERVER['PHP_SELF']); // exit; } catch(PDOException $e) { echo "更新失败: " . $e->getMessage(); } } ?>
关键安全提示
- 预处理语句:一定要用PDO的预处理和参数绑定,绝对不能直接把用户输入拼到SQL语句里,防止SQL注入。
- XSS防护:所有从数据库取出并渲染到页面的内容,都要用
htmlspecialchars()转义。 - CSRF防护:如果是生产环境,建议添加CSRF令牌(比如生成一个随机字符串存在session里,表单里加隐藏字段提交,验证时对比),防止跨站请求伪造。
把以上三部分代码整合到同一个PHP文件里,就能实现“拉取数据→展示可编辑表单→提交更新”的完整流程啦。
内容的提问来源于stack exchange,提问作者Axel Gronberg
相关产品推荐
相关产品推荐

