本文目录导读:

在PHP项目中对接图文推送接口,通常指的是对接微信公众号(或服务号)的图文消息(News) 接口,或者对接第三方推送服务(如极光推送、个推等)的图文消息接口。
由于“图文推送接口”最经典的场景是微信公众号的客服消息或模板消息内的图文,这里以微信公众号的“客服接口-发送图文消息”为例,给出完整的PHP实现方案,其他平台(如企业微信、钉钉、第三方推送)逻辑类似,只是API地址和参数格式不同。
准备工作
基础条件
- 一个已认证的微信公众号(服务号才有客服接口权限)。
- 获取
AppID和AppSecret。 - 服务器IP加入微信白名单(在公众号后台->开发->基本配置中设置)。
获取Access Token
微信接口大多数需要 access_token(有效期2小时,需缓存)。
public function getAccessToken($appid, $appsecret) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
$result = $this->httpGet($url);
return json_decode($result, true)['access_token'] ?? false;
}
HTTP请求辅助函数
public function httpGet($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
public function httpPost($url, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
核心:发送图文消息
微信图文消息是通过 客服接口(/message/custom/send)发送,msgtype 设置为 news。
图文消息格式(最多8条)
{
"touser": "OPENID",
"msgtype": "news",
"news": {
"articles": [
{
"title": "标题",
"description": "描述",
"url": "点击跳转链接",
"picurl": "图片URL"
},
// 可以添加多个
]
}
}
PHP代码实现
public function sendNews($openid, $articles) {
// 1. 获取access_token(通常应缓存,这里简化)
$accessToken = $this->getAccessToken('your_appid', 'your_appsecret');
if (!$accessToken) {
return ['errcode' => -1, 'errmsg' => '获取token失败'];
}
// 2. 构建请求数据
$data = [
'touser' => $openid,
'msgtype' => 'news',
'news' => [
'articles' => $articles
]
];
// 3. 发送POST请求
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$accessToken}";
$result = $this->httpPost($url, $data);
return json_decode($result, true);
}
// 使用示例
$articles = [
[
'title' => 'PHP图文推送教程',
'description' => '点击查看如何对接微信图文接口',
'url' => 'https://example.com/article1',
'picurl' => 'https://example.com/img1.jpg'
],
[
'title' => '第二篇文章',
'description' => '支持多图文',
'url' => 'https://example.com/article2',
'picurl' => 'https://example.com/img2.jpg'
]
];
$result = $sendNews->sendNews('用户OPENID', $articles);
print_r($result);
常见问题与注意事项
图片大小与格式
picurl必须是公网可访问的图片地址,建议尺寸:360x200像素(微信会自动缩放)。- 图片格式支持 JPG、PNG,大小不超过2MB。
- 若使用微信素材库中的图片,需先通过
media/upload上传,获取media_id(但图文接口不支持media_id,只能用URL)。
用户OPENID
- 必须通过微信授权(OAuth2.0)或关注事件获取用户的
OPENID。
频率限制
- 客服接口:每个用户每天最多100条,单公众号2万条/天(服务号)。
- 建议用队列(如Redis)控制发送频率,避免封号。
非微信平台(如极光推送、个推)
如果是对接短信/APP推送,数据结构类似,示例代码:
// 极光推送图文示例(需引入jpush-php-sdk)
$client = new \JPush\Client($appKey, $masterSecret);
$response = $client->push()
->setPlatform('all')
->addAlias('user_alias')
->iosNotification('标题', [
'extras' => ['id' => '001', 'type' => 'news']
])
->androidNotification('标题', [
'title' => '图文推送',
'extras' => ['url' => 'https://example.com']
])
->send();
完整封装类(微信图文推送)
class WeChatNewsSender {
private $appid;
private $appsecret;
private $tokenCacheFile = 'access_token.json';
public function __construct($appid, $appsecret) {
$this->appid = $appid;
$this->appsecret = $appsecret;
}
public function sendNews($openid, $articles) {
$token = $this->getValidToken();
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$token}";
$data = [
'touser' => $openid,
'msgtype' => 'news',
'news' => ['articles' => $articles]
];
return json_decode($this->httpPost($url, $data), true);
}
private function getValidToken() {
// 实际中可以从缓存/数据库读取,这里简化
$tokenData = json_decode(file_get_contents($this->tokenCacheFile), true);
if ($tokenData && $tokenData['expire_time'] > time()) {
return $tokenData['access_token'];
}
$token = $this->fetchToken();
file_put_contents($this->tokenCacheFile, json_encode([
'access_token' => $token,
'expire_time' => time() + 7000 // 预留几分钟过期
]));
return $token;
}
private function fetchToken() {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appsecret}";
$result = json_decode($this->httpGet($url), true);
return $result['access_token'] ?? false;
}
private function httpGet($url) { /* 同上实现 */ }
private function httpPost($url, $data) { /* 同上实现 */ }
}
| 场景 | 接口 | 关键字段 |
|---|---|---|
| 微信图文客服消息 | POST /message/custom/send |
touser, msgtype=news, articles |
| 微信模板消息(带图文) | POST /template/send |
template_id, data, url(跳转链接) |
| 企业微信 | POST /appchat/send |
chatid, msgtype=news, articles |
| 极光/个推推送 | SDK方法 | extras, url,标题内容 |
核心逻辑:
- 获取接口凭证(token / key)
- 构建符合接口规范的JSON数据(图文列表)
- 发起HTTP POST请求
- 处理返回结果(成功/失败)
如果遇到“无效的openid”或“参数错误”,检查 picurl 是否可访问、url 是否完整(建议加 https://)。