PHP通过MAMP向Google Sheets提交表单部分字段失败排查
核心问题分析
从你提供的代码来看,sex和dob字段无法写入Google Sheets的主要原因有两个:
PHP传递了不存在的
date参数,导致GAS执行报错
HTML表单中没有name="date"的输入框,但PHP的$postData里却强行添加了"date" => $_POST['date'],这会导致PHP抛出「未定义索引」警告,同时传递给GAS的date参数为undefined。在GAS中调用e.parameter.date.trim()时,会因为undefined没有trim方法直接报错,导致doPost函数中断,后续的sex和dob参数无法被处理。GAS的
doPost函数未正确返回响应
当前doPost执行完updateRecord后没有返回JSON响应,PHP端curl_exec会拿到空结果,json_decode后得到null,后续逻辑进入错误分支,但实际updateRecord可能已经执行了部分操作(比如写入前三个字段),导致排查混乱。
分步修复
1. 移除无效的date参数链
修改PHP代码(post.php)
删掉$postData中不存在的date字段,同时增加参数合法性检查:
// 先检查必填字段是否存在 $requiredFields = ['email', 'password', 'id', 'sex', 'dob']; foreach ($requiredFields as $field) { if (!isset($_POST[$field]) || empty(trim($_POST[$field]))) { $_SESSION['error'] = "缺少必填字段:{$field}"; header("location: table.php?err=missing_field"); exit; } } $url = "你的App Script部署URL"; $postData = [ "action" => "CRUD", "email" => trim($_POST['email']), "password" => trim($_POST['password']), "id" => trim($_POST['id']), "sex" => trim($_POST['sex']), "dob" => trim($_POST['dob']), ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => $postData ]); $result = curl_exec($ch); // 检查curl请求是否失败 if (curl_errno($ch)) { $_SESSION['error'] = "请求失败:" . curl_error($ch); header("location: table.php?err=curl_failed"); exit; } curl_close($ch); $result = json_decode($result, true); // 检查响应是否合法 if (!$result) { $_SESSION['error'] = "服务器响应无效"; header("location: table.php?err=invalid_response"); exit; } if ($result['status'] == "success") { $_SESSION['success'] = $result['message']; header("location: table.php?success=" . urlencode($result['message'])); } else { $_SESSION['error'] = $result['message']; header("location: table.php?err=" . urlencode($result['message'])); }
修改Google Apps Script代码
删除date相关的参数和数组元素,同时完善响应返回:
function doPost(e) { // 打印日志,方便排查参数接收情况 Logger.log(JSON.stringify(e.parameter)); if (typeof e.parameter.action == 'undefined') { return ContentService.createTextOutput(JSON.stringify({ status: "error", message: "需要指定action参数" })).setMimeType(ContentService.MimeType.JSON); } if (e.parameter.action == "CRUD") { // 处理可能为空的参数,避免trim报错 var sex = e.parameter.sex ? e.parameter.sex.trim() : ""; var dob = e.parameter.dob ? e.parameter.dob.trim() : ""; var result = updateRecord( e.parameter.email.trim(), e.parameter.password.trim(), e.parameter.id.trim(), sex, dob ); return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON); } return ContentService.createTextOutput(JSON.stringify({ status: "error", message: "无效的action参数" })).setMimeType(ContentService.MimeType.JSON); } function updateRecord(email, password, id, sex, dob) { var sheet = SpreadsheetApp.getActiveSpreadsheet(); var mySheet = sheet.getSheetByName("profiledata"); var lastRow = mySheet.getLastRow(); var record = [email, password, id, sex, dob]; var range = mySheet.getRange(2, 1, lastRow - 1); var existingRow = range.createTextFinder(email).findNext(); if (existingRow) { // 更新现有记录 existingRow.offset(0, 0, 1, record.length).setValues([record]); return { status: "success", message: "记录已更新" } } else { // 新增记录,直接定位到最后一行的下一行 mySheet.getRange(lastRow + 1, 1, 1, record.length).setValues([record]); return { status: "success", message: "新记录已创建" } } }
2. 确保Google Sheets列数足够
打开profiledata工作表,确保至少有5列,对应字段顺序:
- Password
- ID
- Sex
- DOB
3. 验证App Script部署配置
确认你的App Script已部署为Web应用,并且:
- 执行权限设置为「我自己」
- 访问权限设置为「任何人,甚至匿名」(测试阶段)
- 部署后复制新生成的URL到PHP代码中(每次修改GAS后都需要重新部署,否则URL无效)
额外排查技巧
在GAS的doPost函数中添加Logger.log(JSON.stringify(e.parameter));,执行表单提交后,打开GAS编辑器的「查看」→「日志」,可以查看实际接收到的参数是否完整,快速定位参数传递问题。
内容的提问来源于stack exchange,提问作者Niyo Zak

