首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取 QQ 使用者暱稱與線上狀態完整解析

     編輯:PHP 綜合知識

背景與原理

騰訊 QQ 提供公開的狀態查詢介面(wpa.qq.com),回傳不同圖片代表線上/離線狀態。早期方案利用圖片 Content-Length 差異判斷;後期介面改為重導向至含 online/offline 關鍵字的 URL,更可靠。暱稱可從 QQ 空間個人名片介面取得。

方案一:HTTP Header Content-Length 判斷(舊版,參考用)

<?php
function get_qq_status($uin) {
    error_reporting(0);
    $f = file_get_contents('https://wpa.qq.com/pa?p=1:' . $uin . ':4');
    if (!$f) return true; // 無法取得視為線上
    
    foreach ($http_response_header as $val) {
        if (strpos($val, 'Content-Length') !== false) {
            return (intval(substr($val, 16)) > 1000); // 彩色圖片較大
        }
    }
    return false;
}
?>

缺點:閾值需經驗調整,騰訊調整圖片大小即失效,不建議生產環境使用。

方案二:Socket 直連分析 Location 標頭(推薦)

<?php
function tphp_qq_online($uin) {
    $request  = "GET /pa?p=1:{$uin}:1 HTTP/1.1\r\n";
    $request .= "Host: wpa.qq.com\r\n";
    $request .= "User-Agent: PHP_QQ_SPY\r\n\r\n";

    if (!($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) return -1;
    if (!socket_connect($socket, "wpa.qq.com", 80)) return -1;
    if (!socket_write($socket, $request)) return -1;
    if (!($respon = socket_read($socket, 1024, PHP_BINARY_READ))) return -1;
    socket_close($socket);

    $fields = explode("\r\n", $respon);
    foreach ($fields as $field) {
        if (strncasecmp($field, "Location:", 9) === 0) {
            if (strpos($field, 'online')) return 1;
            if (strpos($field, 'offline')) return 0;
            return -1;
        }
    }
    return -1;
}

// 使用範例
echo tphp_qq_online(561272831); // 1=線上, 0=離線, -1=未知/錯誤
?>

優點:直接解析 HTTP 重導向邏輯,不依賴圖片大小,穩定性較高。

方案三:get_headers 獲取 Content-Length(簡易版)

<?php
function getQQState($qq) {
    $url = 'https://wpa.qq.com/pa?p=2:' . $qq . ':41&r=' . time();
    $headInfo = get_headers($url, 1);
    $length = $headInfo['Content-Length'] ?? 0;
    // 1243 為離線圖片大小(需實測校準),其他視為線上
    return $length != 1243;
}
?>

獲取 QQ 暱稱

呼叫 QQ 空間個人名片介面,解析 JSONP 回傳內容。

<?php
function getQQNick($qq) {
    $str = file_get_contents('https://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=' . $qq);
    $pattern = '/'.preg_quote('"nickname":"','/').'(.*?)'.preg_quote('",','/').'/i';
    preg_match($pattern, $str, $result);
    return $result[1] ?? '';
}

function getQQName($qq) {
    // 可先從本地快取查找,無則呼叫 API
    $username = getQQNick($qq);
    return $username;
}
?>

整合使用範例

<?php
$qq = '561272831';
$online = tphp_qq_online($qq);
$nick = getQQNick($qq);

echo "QQ: {$qq}<br>";
echo "暱稱: {$nick}<br>";
echo "狀態: " . ($online === 1 ? '線上' : ($online === 0 ? '離線' : '未知')) . "<br>";
?>

注意事項與限制

  1. 頻率限制:騰訊對查詢頻率有嚴格限制,高併發需自建快取(Redis/Memcached),設定合理 TTL(如 5-10 分鐘)。
  2. 介面變更風險:非官方文檔介面,隨時可能失效或變更參數,建議封裝成服務類並加入降級策略。
  3. 隱私合規:僅查詢公開狀態與暱稱,避免儲存敏感資訊,符合個資保護規範。
  4. HTTPS 支援:新版介面已支援 HTTPS,建議改用 https://wpa.qq.com 提升安全性。
  5. 錯誤處理:網路超時、DNS 失敗、回傳格式異常皆需捕獲並回傳預設值,避免阻塞主流程。

總結

Socket 方案(方案二)為目前最穩健的 QQ 線上狀態檢測方式,搭配 QQ 空間名片介面可同時獲取暱稱。實際專務必加入快取層、錯誤重試與監控告警,確保服務可用性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved