codeigniter集成zendesk应选用api token认证,因其不依赖用户会话、适合后台调用;需base64编码邮箱/token并设authorization头,配合accept/content-type: application/json、json_encode请求体、ssl验证配置及完整错误处理与日志记录。

CodeIgniter 本身不提供 Zendesk 官方 SDK,集成必须走 REST API + 手动封装,硬套现成类库大概率失败。
Zendesk API 认证方式选哪一种
Zendesk 支持三种认证:API Token、OAuth 2.0、JWT。对 CodeIgniter 这类无前端会话管理的 PHP 应用,API Token 最直接可靠——它不依赖用户登录态,适合后台服务调用(如工单创建、评论更新)。OAuth 2.0 需要完整授权流程和 token 刷新逻辑,CI 项目若没做 session/cookie 统一管理,极易卡在 invalid_grant 或过期失效;JWT 更适合嵌入 Zendesk Apps 场景,不适用于后端主动调用。
- 使用
API Token时,格式为email/token:your_token,必须 Base64 编码后放入Authorization请求头 - 邮箱必须是 Zendesk 管理员或具备 API 权限的账号,不能是普通客服坐席邮箱
- Token 在 Zendesk 后台「Settings > Account > Channels > API」中生成,每次生成只显示一次,务必保存
封装 Zendesk API 客户端要注意 cURL 设置
直接复用 CodeIgniter 自带的 curl 类或写裸 cURL 都行,但以下参数不可省略,否则常见 401 Unauthorized 或 422 Unprocessable Entity:
-
CURLOPT_SSL_VERIFYPEER必须设为false(仅开发环境)或指向真实 CA bundle 路径(生产环境),Zendesk 的证书链有时触发 OpenSSL 验证失败 -
CURLOPT_HTTPHEADER至少包含Accept: application/json和Content-Type: application/json,缺一不可 -
CURLOPT_RETURNTRANSFER必须为true,否则curl_exec()返回bool(true)而非响应体 - POST 数据必须用
json_encode()编码,不能用http_build_query()(后者发的是application/x-www-form-urlencoded,Zendesk 拒收)
示例片段(放在 application/libraries/Zendesk_api.php):
public function create_ticket($data) {
$url = $this->base_url . '/api/v2/tickets.json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['ticket' => $data]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic ' . base64_encode($this->email . '/token:' . $this->token),
'Accept: application/json',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 生产请替换为 CA 路径
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $http_code === 201 ? json_decode($response, true) : false;
}
配置项别写死在控制器里
把 Zendesk 的 subdomain、email、token、timeout 全部抽到 application/config/zendesk.php,避免硬编码污染业务逻辑:
defined('BASEPATH') OR exit('No direct script access allowed');
$config['zendesk_subdomain'] = 'yourcompany';
$config['zendesk_email'] = 'admin@yourcompany.com';
$config['zendesk_token'] = 'abc123xyz789';
$config['zendesk_timeout'] = 15;
然后在客户端类构造函数中加载:
$this->subdomain = $this->ci->config->item('zendesk_subdomain');
$this->base_url = 'https://' . $this->subdomain . '.zendesk.com';
// ...
- 敏感字段(如
token)建议通过环境变量注入,例如用getenv('ZENDESK_TOKEN')替代配置文件直写 - 如果多个环境(dev/staging/prod)共用一套代码,配置文件中可加判断:
if (ENVIRONMENT === 'production') { $config['zendesk_token'] = getenv('ZENDESK_TOKEN'); }
错误处理不能只靠 try-catch
Zendesk API 返回的不是标准 HTTP 状态码语义:比如工单字段校验失败返回 422,但响应体里有详细错误字段;网络超时或 DNS 失败则根本收不到 JSON。所以仅靠 try-catch 捕获 Exception 不够,必须检查 curl_error() 和 curl_getinfo($ch, CURLINFO_HTTP_CODE):
-
curl_error()非空 → 网络层失败(DNS、连接超时、SSL 握手失败),此时$response为false,不要尝试json_decode() -
HTTP_CODE为401→ 认证失败,优先检查邮箱格式、Token 是否过期或权限不足 -
HTTP_CODE为422→ 查看响应体中的details字段,常见于subject为空、comment缺html_body或plain_body - 所有错误都应记录到
log_message('error', ...),含原始请求 URL、参数摘要、错误信息,方便排查
最易被忽略的是 Zendesk 对请求频率的限制:免费版默认 700 次/分钟,超限返回 429 Too Many Requests,且响应头含 Retry-After。没做退避重试逻辑的服务,在高并发创建工单时会静默失败。











