分析網站流量來源、關鍵字排名追蹤、個性化推薦內容、SEO 效果評估。
$_SERVER['HTTP_REFERER'] 或傳入的 URL 參數。q、wd、query)提取關鍵字。<?php
/**
* 從 Referer URL 解析搜尋引擎與關鍵字
* @param string $url 完整 Referer URL
* @return array ['engine' => 'google', 'keywords' => ['關鍵字1', '關鍵字2']]
*/
function parseSearchEngineKeywords(string $url): array
{
$engines = [
'google.com' => ['param' => 'q', 'charset' => 'UTF-8'],
'google.com.tw' => ['param' => 'q', 'charset' => 'UTF-8'],
'google.com.hk' => ['param' => 'q', 'charset' => 'UTF-8'],
'baidu.com' => ['param' => 'wd', 'charset' => 'GBK'],
'sogou.com' => ['param' => 'query', 'charset' => 'GBK'],
'so.com' => ['param' => 'q', 'charset' => 'UTF-8'], // 360搜尋
'bing.com' => ['param' => 'q', 'charset' => 'UTF-8'],
'yahoo.com' => ['param' => 'p', 'charset' => 'UTF-8'],
'duckduckgo.com' => ['param' => 'q', 'charset' => 'UTF-8'],
'yandex.com' => ['param' => 'text', 'charset' => 'UTF-8'],
];
$parsed = parse_url($url);
if (empty($parsed['host']) || empty($parsed['query'])) {
return ['engine' => 'unknown', 'keywords' => []];
}
$host = strtolower($parsed['host']);
// 移除 www. 前綴以便匹配
$host = preg_replace('/^www\./', '', $host);
foreach ($engines as $domain => $config) {
// 精確匹配域名或子域名
if (strpos($host, $domain) !== false && (strlen($host) === strlen($domain) || substr($host, -strlen($domain)-1) === '.'.$domain)) {
$param = $config['param'] . '=';
$query = $parsed['query'];
// 提取參數值
$start = strpos($query, $param);
if ($start === false) {
return ['engine' => $domain, 'keywords' => []];
}
$start += strlen($param);
$end = strpos($query, '&', $start);
$keywordEncoded = $end !== false ? substr($query, $start, $end - $start) : substr($query, $start);
// URL 解碼
$keyword = urldecode($keywordEncoded);
// 編碼轉換
if (strtoupper($config['charset']) !== 'UTF-8') {
$keyword = @iconv($config['charset'], 'UTF-8//IGNORE', $keyword);
}
// 分割多關鍵字(以空白或 + 分隔)
$keywords = preg_split('/\s+|\+/', trim($keyword), -1, PREG_SPLIT_NO_EMPTY);
return ['engine' => $domain, 'keywords' => $keywords];
}
}
return ['engine' => 'unknown', 'keywords' => []];
}
// 使用範例
$referer = $_SERVER['HTTP_REFERER'] ?? '';
$result = parseSearchEngineKeywords($referer);
echo "引擎: {$result['engine']}\n";
echo "關鍵字: " . implode(', ', $result['keywords']) . "\n";
?>
| 課題 | 處理方式 |
|---|---|
| 域名匹配 | 使用 strpos + 邊界檢查,避免 baidu.com.evil.com 誤判 |
| 參數提取 | 手動解析 Query String,比 parse_str 更精確控制單一參數 |
| 編碼轉換 | 百度/搜狗常用 GBK,需 iconv 轉 UTF-8,//IGNORE 忽略非法字元 |
| 關鍵字分割 | 支援空白、+、全形空白等分隔符 |
| HTTPS Referer 缺失 | 現代瀏覽器跨域 HTTPS→HTTP 不送 Referer,需配合 Search Console / 站長平台數據 |
engine, keyword, landing_page, timestamp, user_id 供後續分析。雖然 HTTPS 普及導致 Referer 關鍵字獲取越來越困難,但對於仍有 HTTP 流量或配合站長工具數據的場景,此解析邏輯依然實用。建議搭配 Google Search Console API、百度站長平台 API 獲取更完整的搜尋關鍵字數據。