应封装为application/libraries/Api_client.php类,统一处理curl请求、prep_url校验、http_build_query/json_encode适配、超时与错误兜底,并将密钥等配置外置到config/api.php,确保脱敏、幂等与自动重试。

CodeIgniter 本身不提供内置 HTTP 客户端,但用好 curl + 框架基础组件(Input、url_helper、config)就能稳定对接绝大多数外部 API,关键在封装方式和错误兜底。
如何封装一个可复用的 API 请求类(CI3)
直接在控制器里写 curl_init() 容易重复、难维护、漏超时或错误处理。应统一收口到 application/libraries/Api_client.php:
- 类名必须与文件名完全一致(
Api_client→Api_client.php),否则$this->load->library('Api_client')会报Unable to load the requested class - 构造函数中用
get_instance()获取 CI 实例,才能调用$this->config->item('api_timeout')等配置 - 务必用
prep_url($url)处理目标地址——漏掉https://或多出空格会导致 cURL 返回Empty reply from server而非具体错误 -
CURLOPT_POSTFIELDS必须传字符串,http_build_query($params)是安全选择;传数组会触发微信/支付宝等平台的INVALID_ARGUMENT
POST 请求体格式和 Content-Type 怎么配才不被拒
很多外部 API(如微信模板消息、阿里云 OpenAPI)对 Content-Type 和请求体结构极其敏感:
- 若 API 文档要求
application/json,则不能用http_build_query(),得用json_encode($params),并显式设置 header:['Content-Type: application/json'] - 若要求
application/x-www-form-urlencoded(如支付宝网关),就必须用http_build_query(),且确保所有参数已按文档规则排序、签名、URL 编码 - 微信 JSAPI 支付的
unifiedorder接口返回INVALID_REQUEST,90% 是因为body字段含中文但没设mb_internal_encoding('UTF-8')或没在curl_setopt中加CURLOPT_ENCODING => 'UTF-8'
异步回调(notify_url)为什么总验签失败
不是密钥错了,就是数据没“原样”拿到——CI 的 $this->input->post() 会自动过滤和转义,而微信/支付宝回调要求原始未处理的 raw body:
- 微信回调必须用
file_get_contents('php://input')读取原始 JSON,再用json_decode(..., true)解析,不能走$this->input->post() - 支付宝回调虽是 form 表单,但
sign字段必须从原始 POST 数据中提取,不能经$this->input->post('sign')过滤,否则大小写或空格被篡改导致openssl_verify()返回 false - 回调入口控制器方法里第一行加
header('Content-Type: text/plain; charset=utf-8');,避免 CI 输出类自动加 HTML 头导致返回值不是纯success
配置和日志怎么管才不踩坑
密钥硬编码在类里、日志记满敏感字段、超时不设——这些都会让线上排查变成盲人摸象:
- 把
access_key_id、endpoint等全挪到application/config/api.php,用$this->config->load('api')加载,别写死在类里 -
endpoint必须带协议和端口,例如阿里云短信是https://dysmsapi.aliyuncs.com,少个s就连不上,cURL 却只报Could not resolve host - 日志记录前必须脱敏:
log_message('info', 'Aliyun SMS request: '.json_encode(array_merge($params, ['SignName' => '***']))); -
api_timeout建议设为 10–15 秒:太短(如 3 秒)易因网络抖动误判失败;太长(如 60 秒)会让用户卡在支付页,也拖垮服务器连接池
真正难的不是调通一次,而是保证重试、幂等、验签、脱敏、配置分离这五件事在每次请求里都自动发生——漏掉任何一环,上线后的问题都是凌晨三点的报警电话。


















