PHP发送API PUT请求提交表单数据报错排查求助
让我仔细检查你的代码,找出几个明显的问题——这些应该就是导致请求失败的核心原因:
1. 变量判断的低级笔误
在$tipoInspecaoId的条件分支里,你犯了一个很容易忽略的错误:后面几个判断条件错误地使用了$tipoInspecaoId ==,而不是$tipoInspecao ==。比如:
// 错误写法 elseif($tipoInspecaoId == "Reinspecção"){ // 正确写法应该是 elseif($tipoInspecao == "Reinspecção"){
这个笔误会导致除了第一个条件外,其他$tipoInspecaoId的赋值逻辑永远不会触发,变量会处于未定义状态,传递给API的参数自然就会缺失或错误。
2. PUT请求的参数格式完全错误
你当前处理参数的逻辑非常奇怪:把参数值塞进无键数组,用http_build_query生成带索引的字符串后,又手动删掉索引键名,得到类似value1/value2/value3的格式。这几乎不可能是API期望的参数格式。
同时你设置的Content-Type: multipart/form-data请求头,和这种参数格式完全不匹配——API根本无法解析你的请求内容。
绝大多数API接收PUT请求时,要么期望键值对形式的表单数据(对应application/x-www-form-urlencoded头),要么是JSON格式的请求体。
3. 缺少CURL错误检查
你只执行了curl_exec,但没有检查请求过程中是否发生了CURL层面的错误(比如网络超时、SSL验证失败、连接失败等)。添加错误检查能帮你快速定位是请求过程出错,还是API返回了业务错误。
4. 潜在的参数缺失问题
代码里$centroID和$tag被注释掉了,如果你的API请求需要这两个参数,当前代码会导致它们缺失,直接引发请求失败。
修正后的代码示例
假设你的API期望接收键值对形式的表单数据(请务必对照API文档确认参数名是否正确),修正后的核心代码如下:
if ($_SERVER["REQUEST_METHOD"] == "POST") { function ediprinterMarcacao(){ $name = trim($_POST["name"]); $dataMarcacao = trim($_POST["data-marcacao"]); $horaMarcacao = trim($_POST["hora-marcacao"]); $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL); $centro = ucfirst(trim($_POST["centro-inspecoes"])); $matricula = trim($_POST["matricula"]); $telefone = trim($_POST["telefone"]); $tipoInspecao = trim($_POST["tipo-inspecao"]); $tipoViatura = trim($_POST["tipo-viatura"]); $comentario = trim($_POST["comentario"]); $formatDate = date("Y-m-d", strtotime($dataMarcacao)); $dataM = str_replace(array('-'), '',$formatDate); $horaM = str_replace(array(':'), '',$horaMarcacao); // 恢复centro相关变量的赋值(如果API需要的话) $centroID = null; $tag = null; if($centro == "Paredes"){ $centroID = 0; $tag = 25; } elseif ($centro == "Braga"){ $centroID = 1; $tag = 26; } $tipoViaturaId = null; if($tipoViatura == "LIGEIRO"){ $tipoViaturaId = 1; } elseif($tipoViatura == "PESADO"){ $tipoViaturaId = 2; } elseif($tipoViatura == "TRACTOR"){ $tipoViaturaId = 3; } elseif($tipoViatura == "REBOQUE"){ $tipoViaturaId = 6; } elseif($tipoViatura == "SEMI-REBOQUE"){ $tipoViaturaId = 7; } elseif($tipoViatura == "TRACTOR < 3500Kg"){ $tipoViaturaId = 9; } // 修复tipoInspecaoId的判断逻辑 $tipoInspecaoId = null; if($tipoInspecao == "Inspecção Periódica"){ $tipoInspecaoId = 1; } elseif($tipoInspecao == "Reinspecção"){ $tipoInspecaoId = 2; } elseif($tipoInspecao == "Insp.p/atrib.nova Matricula"){ $tipoInspecaoId = 3; } elseif($tipoInspecao == "Inspecção Extraordinária"){ $tipoInspecaoId = 4; } elseif($tipoInspecao == "Inspecção Facultativa"){ $tipoInspecaoId = 5; } // 整理符合API要求的参数数组(务必确认参数名和API一致!) $params = [ 'dataM' => $dataM, 'horaM' => $horaM, 'matricula' => $matricula, 'name' => $name, 'email' => $email, 'telefone' => $telefone, 'tipoViaturaId' => $tipoViaturaId, 'tipoInspecaoId' => $tipoInspecaoId, 'centroID' => $centroID, 'tag' => $tag ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://edigcia.ediprinter.pt/edigciaappointmentapi/InsertAppointment188/", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "PUT", // 生成正确的表单键值对 CURLOPT_POSTFIELDS => http_build_query($params), // 设置匹配的Content-Type头 CURLOPT_HTTPHEADER => [ "Content-Type: application/x-www-form-urlencoded", ], ]); $response = curl_exec($curl); // 添加CURL错误检查 if(curl_errno($curl)) { echo 'CURL请求错误: ' . curl_error($curl); } else { echo $response; } curl_close($curl); } ediprinterMarcacao(); }
额外提示
如果你的API期望接收JSON格式的请求体,只需要修改CURL的这两部分:
// 把参数转成JSON字符串 CURLOPT_POSTFIELDS => json_encode($params), // 修改Content-Type头 CURLOPT_HTTPHEADER => [ "Content-Type: application/json", ],
内容的提问来源于stack exchange,提问作者Ricardo Carneiro

