2015-06-29 20 views
8

I już ułożyła mały skrypt w PHP, który sprawdza ustawień językowych twojej i przekierować je do wersji językowej serwisu (WP wielu miejscach),Język przekierowanie działa na pulpicie, ale nie w przeglądarce mobilnej

function redirect() { 
    $language = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2); 
    switch($language) { 
    case 'sv': 
     header('Location: http://www.example.com/sv/'); 
     break; 
    case 'no': 
     header('Location: http://www.example.com/no/'); 
     break; 
    case 'da': 
     header('Location: http://www.example.com/da/'); 
     break; 
    default: 
     header('Location: http://www.example.com/'); 
     break; 
    } 
} 
if (strlen($url) < 4) { 
    session_start(); 
    if (empty($_SESSION[ 'language' ])) { 
    $_SESSION[ 'language' ] = true; 
    redirect(); 
    } 
} 

Podczas testowania z Mobile Safari lub Mobile Chrome przekierowanie nie działa. Czy jest jakiś specjalny wynik dla akceptowanego języka dla przeglądarek mobilnych, który muszę wziąć pod uwagę?

Aktualizacja: Po pewnym więcej debugowania Znalazłem się w ten sposób:

  • Mobile Safari wyświetla odpowiedni język, gdy echo HTTP_ACCEPT_LANGUAGE ale nie przekierować.
  • Chrome mobilna (tylko iOS, działa na Androidzie) nie wyświetla właściwego języka (domyślnie "en").
  • System iOS analizuje dane nagłówka http w innej kolejności, porównuje Chrome iOS (en-US, en; q = 0,8, sv; q = 0,6) i Chrome OSX (sv, en-US; q = 0,8, en; q = 0,6).
+0

Echo 'HTTP_ACCEPT_LANGUAGE' z urządzenia mobilnego jest tam? – chris85

+0

Niestety, zapomniałem wspomnieć - echo to daje mi "en" w wyniku zarówno dla Mobile Safar i Mobile Chrome (iOS 8). –

+0

Wygląda na to, że 'HTTP_ACCEPT_LANGUAGE' nie działa na urządzeniach mobilnych. Możesz poprosić użytkownika o jego język lub wypróbować inną metodę, gdy telefon komórkowy jest mobilny. – chris85

Odpowiedz

1

UPDATE do mojej poprzedniej odpowiedzi

HTTP_ACCEPT_LANGUAGE jest ustawiana za pomocą nagłówków i daje różne wartości dla każdego. W moim przypadku znajduję się w Ameryce Południowej na komputerze w języku angielskim, więc moje nagłówki w języku angielskim mają ustawienia angielski i hiszpański z nastawieniem na angielski.

session_start(); 

function redirectToLang($langCode){ 
    // use if's instead of switch so that you can 
    // check exact matches and presence of a substring 
    if ($langCode == 'sv'){ 
     $langPath = 'sv'; 
    }else if (strpos($langCode, 'en') !== false){ // this would match en, en-CA, en-US 
     $langPath = 'en'; 
    }else if ($langCode == 'no'){ 
     $langPath = 'no'; 
    }else{ 
     $langPath = 'en'; 
    } 

    // you should have no output from the server before this line! 
    // that is no echoes, print_r, var_dumps, headers, etc 
    header('Location: http://www.example.com/' . $langPath .'/'); 
    die(); 
} 

function parseLang(){ 
    // echo $_SERVER['HTTP_ACCEPT_LANGUAGE']; in my case 
    // Chrome Mac OS:  en,es;q=0.8 
    // Chrome Android 5.1: en-US;en;q=0.8,es;q=0.6 
    // IE Windows Phone 8.1: en-US,en;q=0.5 
    // Safari iOS:   en-US 
    // Chrome iOS:   en-US,en;q=0.8 

    // get the lang and set a default 
    $lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : 'en'; 

    // parse the lang code. This can be as simple or as complex as you want 

    // Simple 
    $langCode = substr($lang, 0, 2); // in my case 'en' 

    // Semi Complex (credits to http://www.thefutureoftheweb.com/blog/use-accept-language-header) 
    $languages = array(); 
    preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $lang, $parsed); 

    if (count($parsed[1])) { 
     $languages = array_combine($parsed[1], $parsed[4]); 
     foreach ($languages as $lang => $val) { 
      if ($val === '') $languages[$lang] = 1; 
     } 
     arsort($languages, SORT_NUMERIC); 
    } 
    // var_dump($languages); in my case 
    // array (size=2) 
    // 'en' => int 1 
    // 'es' => string '0.8' 


    $langCode = key($languages); // in my case 'en' 

    return $langCode; 
} 


if (!isset($_SESSION['lang'])){ 
    $langCode = parseLang(); 
    $_SESSION['lang'] = $langCode; 
    redirectToLang($langCode); 
}else{ 
    // we already know the language and it is in $_SESSION 
    // no need to parseLang nor redirect 
} 

W moim przypadku wszystkie urządzenia poprawnie przekierowują. Domyślam się, że jest coś dzieje się na logice, która wywołuje redirect()

// this part 
if (strlen($url) < 4) { 
    session_start(); 
    if (empty($_SESSION[ 'language' ])) { 
    $_SESSION[ 'language' ] = true; 
    redirect(); 
    } 
} 

a var sesji jest pomijając logikę przekierowania. Wypróbuj powyższy kod i wyczyść wszystkie pliki cookie i sesje ze wszystkich urządzeń, aby ustawić $_SESSION['language'] zmienny podczas testowania, aby nie zepsuć wyników. Daj nam znać, co stanie się po Twojej stronie.

4

Spróbuj i daj nam znać wyjście proszę

function redirect() { 
    $language = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2); 

    switch($language) { 
    case 'sv': 
     header('Location: http://www.example.com/sv/'); 
     break; 
    case 'no': 
     header('Location: http://www.example.com/no/'); 
     break; 
    case 'da': 
     header('Location: http://www.example.com/da/'); 
     break; 
    default: 
     die('Default location'); 
    /* if you get this message on mobile devices, then this line 

      $language = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2); 

     is faulty. Perhaps as @chris85 mentioned, HTTP_ACCEPT_LANGUAGE is 
     not populated so mobile behaves as a default by not redirecting to 
     other languages. If this is the case, fix that line 
     and remove the die();*/ 
     header('Location: http://www.example.com/'); 
     break; 
    } 
    die(); // leave this one in. It forces the server to flush data to the browser 
} 
+0

Ok. Wyjście to nic (te same przeglądarki, iOS8). –

+0

FYI, mogę poprawnie wyprowadzić dane wyjściowe na Androida (przy użyciu przeglądarki Mobile Chrome lub macierzystej przeglądarki Android). –

+0

Błąd składniowy 'die ('Default location)' brakujący cytat zamykający. – chris85

1

Działa to dobrze na moim przeglądarek stacjonarnych i urządzeniach przenośnych. Też miałem problemy z sesją tylko na urządzeniach i najczęściej polegałem na pustej zmiennej sesji, aby spełnić wymagania mojego warunku, gdy w rzeczywistości zmienna wciąż istniała, lub po prostu nie było wystąpienia session_id().

? Resetowanie wyczyści sesję.

Uruchomi także przekierowanie, jeśli język się zmienił.

<?php 
    session_start(); 

    if (isset($_REQUEST['reset'])) { 
     unset($_SESSION); 
     $_SESSION['PREVIOUS_SESSION'] = '&cleared=1'; 
    } 

    function redirect($loc) { 
     $_SESSION[ 'language' ] = true; 
     $_SESSION['last_language'] = $language; 
     header('Location: ?r='.$loc.$_SESSION['PREVIOUS_SESSION']); 
    } 

    $language = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2); 

    if ((empty($_SESSION[ 'language' ])) || ($_SESSION['last_language'] != $language)) { 
     redirect($language); 
    } 

    echo '<pre>'; 
    print_r($_SESSION); 
    echo '</pre>'; 

    if (!empty($_SESSION['PREVIOUS_SESSION'])) { 
     unset($_SESSION['PREVIOUS_SESSION']); 
    } 
?> 
+1

'substr ($ _SERVER [" HTTP_ACCEPT_LANGUAGE "], 0,2)' jest dokładnie tym samym kodem, którego używa OP, który nie działa dla jego mobilnych przypadków. – Drakes

+1

To nie jest problem z przekierowaniem, na czym polega problem. W przypadku OP zmienna $ language ma przypisaną wartość "http://www.example.com/", jeśli urządzenie nie zwróci substr ($ _SERVER ["HTTP_ACCEPT_LANGUAGE"], 0,2). Bez usuwania tego. – pokeybit

0

Naprawdę nie powinieneś polegać na otrzymywaniu pierwszych dwóch znaków. Naprawdę powinieneś polegać na sprawdzeniu całego ciągu i zrozumieniu, jaki powinien być najlepszy wybór języka. Te wartości ciągów mają określone znaczenie, na przykład w jednym z przypadków ciągów "problem", faktycznie wykonujesz najbardziej odpowiednie zachowanie, aby pokazać en zamiast sv. Można oczywiście pisać logiki rozpad języka przyjąć, zbadania części składowych, i podjąć odpowiednie działania, ale również może rozważyć użycie coś jak:

http_negotiate_language

to zrobić dla ciebie. Istnieją prawdopodobnie dziesiątki innych skryptów dostępnych z szybkiego wyszukiwania w Google, aby naprawdę działały z tym nagłówkiem w bardziej odpowiedni sposób, niż oglądanie dwóch pierwszych znaków.

Ponadto, można sprawdzić podobne pytanie tutaj: Using the PHP HTTP_ACCEPT_LANGUAGE server variable

1

Należy naprawdę daje nam przykłady tego, co jest wartością $_SERVER["HTTP_ACCEPT_LANGUAGE"] dla trzech przypadków.

W każdym razie, proszę zauważyć, że zgodnie z RFC2616 of HTTP/1.1, wybór języka jest o wiele bardziej skomplikowany niż samo wykonanie dwóch pierwszych znaków nagłówka.

Każdy język zasięgu może być podana wartość skojarzony jakości, który oznacza szacunkową wartość preferencji użytkownika dla języków określonych przez tego zakresu. Wartość domyślna to "q = 1". Dla przykład

Accept-Language: da, en-gb;q=0.8, en;q=0.7 

oznaczałoby: „Wolę Danish, ale akceptuje brytyjskiego angielskiego i inne rodzaje angielskim.”

Nic nie mówi, że te nagłówki są posortowane, ani że preferowany język użytkownika jest pierwszym na liście. I konfiguracji języka nie można również skonfigurować w przeglądarce lub systemie operacyjnym.

Najlepiej, aby wybrać najlepszy język, trzeba przeanalizować ten nagłówek w ten sposób:

  • podzielić ciąg na przecinkami
  • Podział każdego podciągu od charakteru średnik
  • Kiedy wartość liczbowa nie podano, użyj wartości domyślnej 1.0
  • Sortuj wynik używając tej wartości liczbowej
  • Porównaj tę listę z listą języków, które są dostępne na Twojej stronie i znajdź najlepszy.
Powiązane problemy