将API代码转换为PHP CURL时出错,请求排查代码问题
先看你给出的原Python API代码:
url = config.ERPNEXT_URL + "/api/method/erpnext.hr.doctype.employee_checkin.employee_checkin.add_log_based_on_employee_field" headers = { 'Authorization': "token "+ config.ERPNEXT_API_KEY + ":" + config.ERPNEXT_API_SECRET, 'Accept': 'application/json' } data = { 'employee_field_value' : employee_field_value, 'timestamp' : timestamp.__str__(), 'device_id' : device_id, 'log_type' : log_type }
再对比你写的PHP CURL代码,这里有几个明显的问题,我逐个给你拆解:
存在的问题
变量引用语法错误
PHP里访问配置不能用Python的config.ERPNEXT_URL写法,一般PHP配置会存在数组中,要写成$config['ERPNEXT_URL'](如果你的配置是数组结构的话),同理config.ERPNEXT_API_KEY和config.ERPNEXT_API_SECRET也要改成$config['ERPNEXT_API_KEY']、$config['ERPNEXT_API_SECRET']。
另外,Python的timestamp.__str__()是把时间对象转字符串,PHP里如果$timestamp是DateTime对象,要用$timestamp->format('Y-m-d H:i:s')或者(string)$timestamp来转换;还有所有变量比如employee_field_value、device_id都要加$前缀(比如$employee_field_value),不然PHP会把它们当成字符串常量,直接报错。CURL句柄变量不统一
你初始化的CURL句柄是$tuCurl,但设置HTTP头的时候却用了$ch——这个变量根本没定义,会导致授权头和Content-Type头完全没被设置,请求肯定会因为权限问题失败。要把curl_setopt($ch, ...)改成curl_setopt($tuCurl, ...)。POST数据格式不对
原Python代码是发送JSON格式的数据,但你直接把PHP数组传给CURLOPT_POSTFIELDS,PHP会默认把数组编码成application/x-www-form-urlencoded格式,和API要求的JSON不匹配。必须先用json_encode()把数组转成JSON字符串,再传给CURLOPT_POSTFIELDS。缺少
Accept请求头
原API请求里明确带了Accept: application/json头,告诉服务器你期望返回JSON格式的数据,你的PHP代码里漏掉了这个头,虽然部分服务器会默认返回JSON,但加上它能避免不必要的兼容性问题,记得加到HTTP头数组里。输出内容错误
请求成功的分支里你写了echo $tuCurl;,这输出的是CURL的资源句柄(比如Resource id #1),不是API返回的实际数据,要改成echo $tuData;才能看到正确的响应。
修正后的完整代码示例
// 假设你的配置存储在$config数组中 $url = $config['ERPNEXT_URL'] . "/api/method/erpnext.hr.doctype.employee_checkin.employee_checkin.add_log_based_on_employee_field"; // 组装请求数据,注意变量前缀和时间转换 $data = array( 'employee_field_value' => $employee_field_value, 'timestamp' => $timestamp->format('Y-m-d H:i:s'), // 假设$timestamp是DateTime对象 'device_id' => $device_id, 'log_type' => $log_type ); $tuCurl = curl_init(); curl_setopt($tuCurl, CURLOPT_URL, $url); curl_setopt($tuCurl, CURLOPT_HEADER, 0); curl_setopt($tuCurl, CURLOPT_POST, 1); curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1); // 将数组转为JSON字符串,符合API要求的格式 curl_setopt($tuCurl, CURLOPT_POSTFIELDS, json_encode($data)); // 设置完整的HTTP请求头,包含Accept、Content-Type和Authorization curl_setopt($tuCurl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Accept: application/json', 'Authorization: token ' . $config['ERPNEXT_API_KEY'] . ":" . $config['ERPNEXT_API_SECRET'] )); $tuData = curl_exec($tuCurl); if(!curl_errno($tuCurl)){ // 输出API返回的响应数据 echo $tuData; } else { echo 'Curl error: ' . curl_error($tuCurl); } curl_close($tuCurl);
内容的提问来源于stack exchange,提问作者Ali Jutt

