騰訊未提供官方公開 API 獲取 QQ 昵稱與在線狀態,開發者需通過非官方接口(如 QQ 空間、wpa.qq.com、網頁版聊天組件)實現。本文匯總三種主流方案並分析優劣。
原理:騰訊返回不同大小的圖片表示在線/離線,通過 HTTP 頭 Content-Length 區分。
<?php
/**
* 獲取 QQ 在線狀態(簡易版)
* @param int|string $uin QQ 號
* @return bool true=在線, false=離線/失敗
*/
function getQqOnlineSimple(string $uin): bool
{
$url = "https://wpa.qq.com/pa?p=1:{$uin}:4";
$content = @file_get_contents($url);
if ($content === false) {
return false;
}
// 從響應頭獲取 Content-Length
foreach ($http_response_header as $header) {
if (stripos($header, 'Content-Length:') === 0) {
$length = (int)trim(substr($header, 15));
// 經驗閾值:在線圖片通常 > 1000 字節
return $length > 1000;
}
}
return false;
}
// 使用
var_dump(getQqOnlineSimple('561272831'));
?>
原理:模擬 HTTP 請求,解析響應頭中 Location 跳轉 URL 是否包含 online 或 offline 關鍵字。
<?php
/**
* Socket 方式獲取 QQ 在線狀態
* @return int 1=在線, 0=離線, -1=失敗
*/
function getQqOnlineSocket(string $uin): int
{
$request = "GET /pa?p=1:{$uin}:1 HTTP/1.1\r\n"
. "Host: wpa.qq.com\r\n"
. "User-Agent: PHP_QQ_Checker\r\n"
. "Connection: Close\r\n\r\n";
$socket = @fsockopen('wpa.qq.com', 80, $errno, $errstr, 5);
if (!$socket) {
return -1;
}
fwrite($socket, $request);
$response = '';
while (!feof($socket)) {
$response .= fread($socket, 1024);
}
fclose($socket);
// 解析 Location 頭
if (preg_match('/Location:\s*(.+)/i', $response, $m)) {
$location = $m[1];
if (strpos($location, 'online') !== false) return 1;
if (strpos($location, 'offline') !== false) return 0;
}
return -1;
}
?>
<?php
/**
* 獲取 QQ 昵稱
* @return string|false 昵稱或失敗
*/
function getQqNickname(string $uin): string|false
{
$url = "https://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin={$uin}";
$json = @file_get_contents($url);
if ($json === false) {
return false;
}
// 響應格式:portraitCallBack({"nickname":"xxx",...})
if (preg_match('/"nickname"\s*:\s*"([^"]+)"/', $json, $m)) {
return $m[1];
}
return false;
}
/**
* 綜合獲取:昵稱 + 在線狀態
*/
function getQqInfo(string $uin): array
{
return [
'uin' => $uin,
'nickname' => getQqNickname($uin) ?? '未知',
'online' => getQqOnlineSimple($uin), // 或使用 Socket 版
];
}
// 批量查詢示例
$qqList = ['561272831', '12345678', '88888888'];
foreach ($qqList as $qq) {
print_r(getQqInfo($qq));
usleep(200000); // 禮貌延遲,避免被限流
}
?>
| 方案 | 獲取信息 | 準確度 | 穩定性 | 速度 | 備註 |
|---|---|---|---|---|---|
| Content-Length | 僅在線狀態 | 中 | 中 | 快 | 閾值可能隨騰訊更新失效 |
| Socket+Location | 僅在線狀態 | 高 | 高 | 中 | 解析跳轉邏輯較穩定 |
| QQ空間接口 | 昵稱+頭像等 | 高 | 中 | 中 | 可能需 Cookie/Referer |