如何在原生PHP中通过cURL实现与WordPress wp_remote_post一致的函数
兼容WordPress wp_remote_post的cURL实现方案
现有代码问题梳理
- 逻辑错误:设置
CURLOPT_POSTFIELDS的判断条件错写为!empty($header),未传header时POST数据不会被发送 - 硬编码请求头:强制覆盖Content-Type为
application/json,不符合wp_remote_post的默认处理逻辑——传入数组类型的请求体时会自动设置为application/x-www-form-urlencoded,仅当传入JSON字符串时才需要手动指定Content-Type - 缺失POST请求标识:未设置
CURLOPT_POST = true,部分场景下cURL不会识别为POST请求 - 缺少SSL适配配置:
wp_remote_post默认支持SSL证书校验,也可通过参数关闭校验适配自签名证书场景 - 返回值结构不匹配:你现有代码直接返回响应体字符串,
wp_remote_post返回的是包含响应头、HTTP状态码、响应体、Cookie的结构化数组,请求失败时返回错误对象
完全兼容的实现代码
function curl_post_wp_compatible($url, $args = []) { // 合并默认参数,和wp_remote_post参数对齐 $default_args = [ 'headers' => [], 'body' => null, 'timeout' => 30, 'user-agent' => 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url'), // 和WP默认UA一致 'sslverify' => true, 'follow_location' => true, 'max_redirects' => 5, ]; $args = array_merge($default_args, $args); $ch = curl_init($url); // 基础POST配置 curl_setopt($ch, CURLOPT_POST, true); if (!is_null($args['body'])) { curl_setopt($ch, CURLOPT_POSTFIELDS, $args['body']); } // 超时配置 curl_setopt($ch, CURLOPT_TIMEOUT, $args['timeout']); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $args['timeout']); // 请求头处理 $headers = []; foreach ($args['headers'] as $key => $value) { $headers[] = is_int($key) ? $value : "$key: $value"; } if (!empty($headers)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // UA配置 curl_setopt($ch, CURLOPT_USERAGENT, $args['user-agent']); // 重定向配置 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $args['follow_location']); curl_setopt($ch, CURLOPT_MAXREDIRS, $args['max_redirects']); curl_setopt($ch, CURLOPT_AUTOREFERER, true); // SSL配置 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $args['sslverify']); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $args['sslverify'] ? 2 : 0); // 响应捕获配置 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); // 同时捕获响应头 curl_setopt($ch, CURLOPT_VERBOSE, false); $response = curl_exec($ch); $curl_error = curl_error($ch); // 请求错误处理 if ($curl_error) { curl_close($ch); // 模拟WP_Error结构,不需要WP环境可直接返回错误数组 if (class_exists('WP_Error')) { return new WP_Error('curl_error', $curl_error); } return [ 'error' => true, 'message' => $curl_error ]; } // 拆分响应头和响应体 $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $response_headers_raw = substr($response, 0, $header_size); $response_body = substr($response, $header_size); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 解析响应头为关联数组,和wp_remote_post格式对齐 $response_headers = []; $headers_lines = explode("\r\n", $response_headers_raw); array_shift($headers_lines); // 移除状态行 foreach ($headers_lines as $line) { if (empty($line)) continue; $parts = explode(':', $line, 2); if (count($parts) == 2) { $key = trim($parts[0]); $value = trim($parts[1]); $response_headers[strtolower($key)] = $value; } } // 组装返回结构,完全和wp_remote_post对齐 return [ 'headers' => $response_headers, 'body' => $response_body, 'response' => [ 'code' => $http_code, 'message' => get_status_header_desc($http_code) // WP内置函数,无WP环境可自定义状态描述映射 ], 'cookies' => [] // 需要解析Cookie可补充对应逻辑,和WP返回格式一致 ]; }
使用示例
和wp_remote_post调用方式完全一致:
// 普通表单POST请求 $response = curl_post_wp_compatible('https://example.com/api', [ 'body' => [ 'name' => 'test', 'age' => 18 ], 'timeout' => 10 ]); // JSON POST请求 $response = curl_post_wp_compatible('https://example.com/api', [ 'headers' => [ 'Content-Type' => 'application/json' ], 'body' => json_encode(['name' => 'test']), 'sslverify' => false // 关闭SSL校验适配自签名证书 ]);
内容的提问来源于stack exchange,提问作者vaibhav kulkarni
相关产品推荐
相关产品推荐

