PHP上传电子签名时无法插入数据库记录无报错问题排查
问题根因
插入逻辑不生效是代码存在多处语法和逻辑错误导致:
- 执行顺序混乱:签名文件存储逻辑写在表单提交判断外,页面GET访问时就会尝试读取POST参数触发报错,且拼接存储路径时提前使用了未定义的
$name变量 - 表单判断字段名错误:判断条件里写的
$_POST['$name']、$_POST['$file']带了多余的$符号,前端不存在这两个提交字段,判断永远不会进入数据库插入分支 - 变量引用错误:插入逻辑中
auto未加单引号属于未定义常量,入库传参使用了不存在的$_POST['$file'],没有传入实际生成的签名文件存储路径 - 数据库操作不严谨:INSERT语句未指定写入字段,若表字段顺序不匹配会直接写入失败;未开启PDO错误提示,所有操作报错都被静默,所以看不到错误日志
- 缺少前置校验:没有判断upload目录权限、签名参数是否为空,文件写入失败时也没有任何提示
修复后实现
PHP后端代码
<?php include '../../main.php'; check_loggedin($pdo); // 临时开启报错,排查完可注释 error_reporting(E_ALL); ini_set('display_errors', 1); // 开启PDO错误模式 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $msg = null; $contact = null; // 先校验客户ID参数 if (!isset($_GET['id'])) { exit('No ID specified!'); } $client_id = intval($_GET['id']); // 查询客户信息 $stmt = $pdo->prepare('SELECT * FROM contacts WHERE id = ?'); $stmt->execute([$client_id]); $contact = $stmt->fetch(PDO::FETCH_ASSOC); if (!$contact) { exit('Contact not exist'); } // 查询账号信息 $stmt = $pdo->prepare('SELECT id,username FROM accounts'); $stmt->execute(); $all_account_info = $stmt->fetchAll(PDO::FETCH_ASSOC); // 仅POST提交时处理签名上传 if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 校验必填参数 if (empty($_POST['name']) || empty($_POST['signature'])) { $msg = "请填写签名人姓名并完成签名绘制"; } else { $name = trim($_POST['name']); $folderPath = "upload/"; // 校验目录存在且可写 if (!is_dir($folderPath)) { mkdir($folderPath, 0755, true); } // 处理base64签名 $image_parts = explode(";base64,", $_POST['signature']); $image_type_aux = explode("image/", $image_parts[0]); $image_type = $image_type_aux[1] ?? 'png'; $image_base64 = base64_decode($image_parts[1]); // 生成存储路径 $file = $folderPath . $name . "_" . uniqid() . '.' . $image_type; // 写入文件 if (file_put_contents($file, $image_base64)) { // 写入数据库,明确指定字段,id为自增主键传null即可 $stmt = $pdo->prepare('INSERT INTO esign (client_id, name, signature_img) VALUES (?, ?, ?)'); $stmt->execute([$client_id, $name, $file]); $msg = "Signature has been recorded."; } else { $msg = "签名文件写入失败,请检查upload目录权限"; } } } ?>
前端表单代码
前端代码逻辑基本正常,需确保签名板初始化JS正确将绘制的签名base64值赋值给name为signature的隐藏textarea,提交时该字段不为空:
<form action="add-sig.php?id=<?=$contact['id']?>" method="post"> <h1>Signature Pad</h1> <div class="col-md-12"> <label class="form-label" for="name">Name</label> <input class="form-control" id="name" name="name" required type="text"> </div> <div class="col-md-12"> <label for="">Signature:</label><br> <div id="sig"></div><br> <textarea id="signature64" name="signature" style="display: none"></textarea> <div class="col-12"> <button class="btn btn-sm btn-warning" id="clear" type="button">⌫Clear Signature</button> </div> </div> <br> <button class="btn btn-success" name="submit" type="submit">Submit</button> <?php if ($msg): ?> <div class="alert mt-2"><?=$msg?></div> <?php endif; ?> </form>
注意:清空签名按钮要加
type="button",否则点击会误触发表单提交
数据表结构确认
确保esign表的id字段设置为自增主键,修正后的表结构:
CREATE TABLE `esign` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `client_id` int(11) NOT NULL, `name` varchar(100) NOT NULL, `signature_img` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
验证步骤
- 先确认站点目录下的
upload文件夹存在,且PHP运行进程有该目录的读写权限 - 提交表单后先检查upload目录是否生成对应签名图片
- 图片生成正常的话,再查询数据库esign表是否新增对应客户的签名记录
- 若仍有问题,保留开头的报错开启代码,根据页面输出的错误信息定位即可
内容的提问来源于stack exchange,提问作者user19406536
相关产品推荐
相关产品推荐

