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

PHP 根據瀏覽器語言自動跳轉至對應語言頁面的實現方案

     編輯:PHP 相關知識

前言:多語言站點的第一體驗優化

用戶訪問多語言站點時,若能根據瀏覽器 Accept-Language 標頭自動導向對應語言版本,將顯著提升轉化率。本文提供一份生產級可用的 PHP 實現,涵蓋語言代碼解析優先級、地區變體處理、回退策略、緩存友好重定向及測試驗證方法。

核心代碼:語言檢測與重定向邏輯

<?php
/**
 * 根據 HTTP_ACCEPT_LANGUAGE 自動重定向到對應語言版本
 * 支持:zh-HK/zh-TW → 繁體 | zh-CN/zh-SG → 簡體 | en-* → 英文 | 其他 → 默認英文
 */
function redirectByBrowserLanguage(): never
{
    // 1. 獲取並標準化語言標頭
    $acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
    $acceptLang = strtolower(trim($acceptLang));
    
    if ($acceptLang === '') {
        // 無標頭:直接走默認
        gotoDefault();
    }

    // 2. 解析優先級列表 (按 q-value 排序)
    // 格式: "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7"
    $langs = [];
    foreach (explode(',', $acceptLang) as $part) {
        $part = trim($part);
        $q = 1.0;
        if (strpos($part, ';q=') !== false) {
            [$tag, $qv] = explode(';q=', $part, 2);
            $q = (float)$qv;
            $part = trim($tag);
        }
        $langs[$part] = $q;
    }
    arsort($langs); // 按優先級降序

    // 3. 定義語言映射規則 (按優先級順序)
    $rules = [
        // 繁體中文地區
        '/^zh[_-](hk|tw|mo)$/i'   => 'zh-Hant', // 香港/台灣/澳門
        // 簡體中文地區
        '/^zh[_-](cn|sg|my)$/i'   => 'zh-Hans', // 大陸/新加坡/馬來西亞
        // 英文系
        '/^en/ i'                 => 'en',
        // 日語/韓語/其他可擴展
        '/^ja/ i'                 => 'ja',
        '/^ko/ i'                 => 'ko',
    ];

    // 4. 匹配最優語言
    foreach ($langs as $langTag => $q) {
        foreach ($rules as $pattern => $locale) {
            if (preg_match($pattern, $langTag)) {
                redirectToLocale($locale);
            }
        }
    }

    // 5. 都不匹配 → 默認
    gotoDefault();
}

function redirectToLocale(string $locale): never
{
    // 避免重定向循環:檢查當前已在目標語言路徑
    $currentPath = $_SERVER['REQUEST_URI'] ?? '/';
    if (str_starts_with($currentPath, "/{$locale}/")) {
        return; // 已在正確語言,不再跳轉
    }
    
    $targetUrl = "/{$locale}/index.php"; // 或由路由系統生成
    // SEO 友好:302 臨時重定向 (語言選擇非永久)
    header("Location: {$targetUrl}", true, 302);
    exit;
}

function gotoDefault(): never
{
    redirectToLocale('en'); // 默認英文
}

// 執行
redirectByBrowserLanguage();

關鍵點深度解析

1. Accept-Language 標頭完整解析

瀏覽器發送示例:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7

  • 語言標簽:BCP 47 格式,如 zh-CN、en-US、zh-Hant-HK
  • 質量值:q=0.9 表示偏好度 (0-1),省略默認 1.0
  • 排序規則:按 q 值降序,同 q 值按出現順序

上述代碼完整實現了 q-value 排序,而非簡單的 preg_match 順序匹配,確保尊重用戶真實偏好。

2. 繁簡中文地區碼映射表

語言標簽地區目標語系備註
zh-CN, zh-SG, zh-MY中國大陸/新加坡/馬來西亞zh-Hans (簡體)官方簡體
zh-TW, zh-HK, zh-MO台灣/香港/澳門zh-Hant (繁體)官方繁體
zh (無地區)通用中文zh-Hans回退策略:默認簡體

3. 避免重定向循環的關鍵檢查

若無此判斷,用戶手動切換語言後再刷新,會被強制拉回瀏覽器語言,體驗極差。

4. SEO 與緩存考量

  • 302 Found:語言跳轉屬臨時性,保留原 URL 收錄權重
  • Vary: Accept-Language:響應頭添加 header('Vary: Accept-Language'),告知 CDN/代理按語言緩存不同版本
  • Canonical + hreflang:各語言頁面需輸出 <link rel="alternate" hreflang="..." href="...">,幫助搜索引擎識別多語言版本

進階:結合 GeoIP 做雙重保險

瀏覽器語言不可靠 (用戶可能設置錯誤、使用 VPN),生產環境建議 GeoIP 為主,Accept-Language 為輔:

測試驗證清單

測試場景模擬方法預期結果
香港用戶 (繁體)ModHeader 設置 Accept-Language: zh-HK,zh;q=0.9跳轉 /zh-Hant/
台灣用戶 (繁體)zh-TW,zh;q=0.9跳轉 /zh-Hant/
大陸用戶 (簡體)zh-CN,zh;q=0.9跳轉 /zh-Hans/
美國用戶 (英文)en-US,en;q=0.9跳轉 /en/
多語言偏好zh-TW,zh-CN;q=0.8,en;q=0.7按 q 值跳轉 /zh-Hant/
無標頭 / 爬蟲清空 Header跳轉 /en/ (默認)
已在目標語言頁訪問 /zh-Hant/about.php不重定向 (避免循環)

現代框架集成提示

  • Laravel:寫成 Middleware,綁定 kernel.php 的 web 組,配合 Laravel-Localization 包
  • Symfony:實現 RequestListener 或使用 JMSI18nRoutingBundle
  • ThinkPHP:行為擴展 Behavior\CheckLang 或中間件
  • 原生 PHP:放入公共入口文件 common.php 最頂部,session_start() 之前

總結

一個健壯的語言自動跳轉方案,核心在於:完整解析 q-value、精準映射繁簡地區碼、防重定向循環、SEO 友好頭部、GeoIP 雙重校驗。本文代碼開箱即用,可直接集成至項目入口,並建議配合前端語言選擇器 (持久化到 Cookie/LocalStorage) 實現「自動推薦 + 手動覆蓋」的最佳體驗閉環。

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