如何实现兼具保存/更新功能的按钮及PHP if-else语法排查
实现UPSERT(保存/更新)按钮的PHP解决方案
嘿,我来帮你搞定这个「存在则更新,不存在则插入」的按钮功能,顺便梳理下你现有代码里的几个问题,再给你搭好正确的if-else逻辑:
先说说你现有代码的潜在坑
- SQL注入风险拉满:开头的
SELECT直接把$_POST[docID]拼进SQL里,完全没做安全处理,这很容易被攻击 - 没做错误检查:比如
mysqli_query万一执行失败(比如数据库挂了、SQL写错),你根本不知道问题出在哪 - 逻辑不完整:只查了数据库,但没写后续的插入/更新分支,等于白忙活了
- 字段校验不严谨:没检查
$_POST里的关键字段(比如docID)是不是真的传过来了,空提交也会跑代码
完整的可运行代码(带正确的if-else逻辑)
下面是修正后的代码,一步步实现你要的功能,还加了安全和错误处理:
<?php // 先启动Session,必须在任何输出之前哦 session_start(); ob_start(); // 引入数据库连接,顺便检查连接成功没 include "../dbcon.php"; if (!$con) { die("数据库连不上啊兄弟: " . mysqli_connect_error()); } // 先确认是POST请求,而且关键的docID字段存在 if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['docID'])) { // 先把POST数据转义,防止SQL注入(更推荐用预处理语句,后面会说) $docID = mysqli_real_escape_string($con, $_POST["docID"]); $docSIG_Contract = mysqli_real_escape_string($con, $_POST["docSIG_Contract"] ?? ''); // 这里把你需要的其他字段也加上,比如docName、docUploadTime之类的 // 第一步:查这个docID的记录有没有存在 $checkSql = "SELECT docID FROM clientdocuments WHERE docID = '$docID'"; $checkResult = mysqli_query($con, $checkSql); // 检查查询是不是成功了 if (!$checkResult) { die("查数据库失败了: " . mysqli_error($con)); } // 核心的if-else判断! if (mysqli_num_rows($checkResult) > 0) { // 记录存在,执行更新操作 $updateSql = "UPDATE clientdocuments SET docSIG_Contract = '$docSIG_Contract' -- 这里加其他要更新的字段,用逗号隔开哈 WHERE docID = '$docID'"; if (mysqli_query($con, $updateSql)) { $message = "搞定!记录更新成功~"; } else { $message = "更新崩了: " . mysqli_error($con); } } else { // 记录不存在,执行插入操作 $insertSql = "INSERT INTO clientdocuments (docID, docSIG_Contract) VALUES ('$docID', '$docSIG_Contract')"; // 这里要把所有需要插入的字段都加到括号和VALUES里哦 if (mysqli_query($con, $insertSql)) { $message = "完美!新记录保存成功~"; } else { $message = "保存失败了: " . mysqli_error($con); } } // 用完数据库记得关掉连接 mysqli_close($con); } else { $message = "喂,得提交有效的表单数据啊!"; } // 输出提示信息,你可以改成跳转到页面或者弹框之类的 echo $message; ob_end_flush(); ?>
关键逻辑拆解
- 请求校验:先用
$_SERVER['REQUEST_METHOD'] === 'POST'确保是表单提交的请求,同时检查docID不为空,避免瞎提交 - 存在性判断:用
mysqli_num_rows($checkResult)看查询结果有多少行,大于0就说明这条记录已经在数据库里了 - 安全升级:上面用了
mysqli_real_escape_string转义数据,但更推荐用预处理语句,彻底杜绝SQL注入,给你个示例:
更安全的预处理语句版本(强烈推荐)
// 检查记录是否存在的预处理写法 $checkStmt = mysqli_prepare($con, "SELECT docID FROM clientdocuments WHERE docID = ?"); mysqli_stmt_bind_param($checkStmt, "s", $docID); // "s"表示字符串类型,数字用"i" mysqli_stmt_execute($checkStmt); mysqli_stmt_store_result($checkStmt); if (mysqli_stmt_num_rows($checkStmt) > 0) { // 更新的预处理语句 $updateStmt = mysqli_prepare($con, "UPDATE clientdocuments SET docSIG_Contract = ? WHERE docID = ?"); mysqli_stmt_bind_param($updateStmt, "ss", $docSIG_Contract, $docID); $updateSuccess = mysqli_stmt_execute($updateStmt); $message = $updateSuccess ? "更新成功啦!" : "更新失败: " . mysqli_stmt_error($updateStmt); } else { // 插入的预处理语句 $insertStmt = mysqli_prepare($con, "INSERT INTO clientdocuments (docID, docSIG_Contract) VALUES (?, ?)"); mysqli_stmt_bind_param($insertStmt, "ss", $docID, $docSIG_Contract); $insertSuccess = mysqli_stmt_execute($insertStmt); $message = $insertSuccess ? "保存成功!" : "保存失败: " . mysqli_stmt_error($insertStmt); }
最后提醒几点
- 一定要确保你的
clientdocuments表中docID是唯一键(主键或者唯一索引),不然判断记录是否存在会出错 - 前端最好也加个字段验证,比如
docID不能为空,这样能减少无效请求 ob_start()和ob_end_flush()是用来控制输出缓冲的,防止session或者header出现"已输出内容"的错误
内容的提问来源于stack exchange,提问作者wannabes
相关产品推荐
相关产品推荐

