I've put together a small script in PHP that checks for the browser's language settings and redirect them to a language version of the site (WP multisite),
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();
}
}
When testing with Mobile Safari or Mobile Chrome the redirect doesn't appear to work. Is there any special output for the accept language for mobile browsers that I need to consider?
Update: After some more debugging I found out this:
UPDATE to my previous answer
The HTTP_ACCEPT_LANGUAGE is set via headers and will give different values for everyone. In my case I am in south america on an computer setup in english so my lang headers have english and spanish settings with a bias towards english.
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
}
In my case, all devices redirect correctly. My guess is that there is something happening on the logic that calls redirect()
// this part
if ( strlen($url) < 4 ) {
session_start();
if ( empty($_SESSION[ 'language' ]) ) {
$_SESSION[ 'language' ] = true;
redirect();
}
}
and the session var
is bypassing the redirect logic. Try the code above and clear all cookies and sessions from all devices so that the $_SESSION['language']
var you have
set during testing wont mess up the results. Let us know what happens on your end.
I'm quoting.. "A more contemporary method would be to use http_negotiate_language():"
Did you check this one? Using the PHP HTTP_ACCEPT_LANGUAGE server variable
This works fine on my desktop browsers, and mobile devices. I too was experiencing session problems on devices only and most often, I was relying on a session variable being empty to fulfill the requirements of my condition when in fact the variable was still in existence, or there simply was no session_id() instantiated.
?reset will clear the session.
It also will run the redirect if the language has changed.
<?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']);
}
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With