Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Detecter la langue preferee de l'user agent

5 réponses
Avatar
Sebastien
Bonjour à tous,


Je cherche un script fiable et SIMPLE pour détecter la langue préférée
de l'user agent.

Par exemple si je reçois par HTTP_ACCEPT_LANGUAGE :
fr;q=1.0,en;q=0.9
je sais que je dois envoyer du français et à défaut de l'anglais.
(Il faut savoir que tous les UA ne renvoient pas le même format.)

J'ai vu des scripts trop compliqués. Ce dont j'ai besoin c'est de savoir
quelle sont les langues acceptées par l'UA dans leur ordre de préférence.

Je me charge ensuite de transférer ces informations dans le xml:lang (si
les infos retournées peuvent être au format "fr" ou "fr-FR" c'est tout
bénéfice) et bien sûr d'adapter le contenu de la page.

J'espère que c'est assez clair.


Sébastien

5 réponses

Avatar
loufoque
Sebastien a dit le 27/03/2005 à 11:50:

Je cherche un script fiable et SIMPLE pour détecter la langue préférée
de l'user agent.



Voici une fonction générique que j'utilisais dans une classe que je t'ai
un peu adaptée.

function negotiateLanguage($items)
{
$header = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$items = array_map('strtolower', $items);
$item = '';
$q_prefs = 0.0;

$total = preg_match_all(
'/(?<=^|,)x20*([^;,]+)(?:;q=(d.d))?x20*(?=,|$)/',
$header,
$matches
);

for( $i = 0; $i < $total; $i++ )
{
$item_tmp = strtolower($matches[1][$i]);
$q_tmp = ( !empty($matches[2][$i]) ) ? $matches[2][$i] : 1.0;

if( in_array($item_tmp, $items) && $q_tmp > $q_prefs )
{
$item = $item_tmp;
$q_prefs = $q_tmp;
}
}

return $item;
}

Il suffit d'appeler negotiateLanguage(array('fr', 'en')); avec les
langues que tu proposes (par ordre de préférence) et ça te retourne la
langue à utiliser au final.
Par contre "en" ne fonctionne pas avec "en-us" et trucs du style.

Avatar
Matt
loufoque wrote:
Sebastien a dit le 27/03/2005 à 11:50:

Je cherche un script fiable et SIMPLE pour détecter la langue préférée
de l'user agent.




function get_accepted_languages() {
$a = explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
if(count($a)<2) { return array($a[0]);}
$aRet = array();
$i=0;
foreach($a as $v) {
$p = explode(',', $v);
if(count($p)<2) {
if(!ereg('q=', $p[0])) {
$aRet[] = $p[0];
}
}else{
foreach($p as $l) {
if(!ereg('q=', $l)) {
$aRet[] = $l;
}
}
}
}
return $aRet;
}

cette fonction te retournera par exemple:
Array ( [0] => en [1] => fr [2] => fr-fr [3] => en-us )


--
Matthias Etienne
http://www.php-help.net


Avatar
loufoque
Matt a dit le 28/03/2005 à 02:09:

if(!ereg('q=', $p[0])) {


preg_match est plus rapide, et pourtant on trouve sur sa documentation
Tip: Do not use preg_match() if you only want to check if one string is
contained in another string. Use strpos() or strstr() instead as they
will be faster.

En effet, ici, tu n'as besoin que de strpos().

Avatar
Sebastien

Par contre "en" ne fonctionne pas avec "en-us" et trucs du style.



Petite question complémentaire dans ce cas : est-ce que tous les
user-agent retournent forcément une langue générique quand ils
supportent différents sous-groupes. C'est ce que fait Mozilla, mais
est-ce un standard, et surtout est-il respecté ?

Ce n'est pas critique pour moi puisqu'il n'y aura qu'une seule version
française (les Belges, Suisses et Québequois se paieront un traducteur
;-)) et une seule version anglaise (les Canadiens, Australiens et le
reste du monde parlent déjà l'anglais Américain). Bref...

En tout cas loufoque ton script est excellent ! Il réagit bien avec
Opera 8 beta2, Opera 7.54, Firefox 1.0.1 (oui, oui, je le mets à jour
tout de suite!), IE5.01, IE5.5, IE6, Lynx 2-8-5, qui retournent chacun
une chaîne différente pour HTTP_ACCEPT_LANGUAGE.

Matt, ton script fonctionne également, et permet même d'accéder aux
régionalisations des langues. Je le garde donc en réserve (avec ta
permission) mais étant dans le top 100 des développeurs les plus
parésseux, je vais utiliser celui de loufoque qui correspond à mon
besoin très simple.

Le fait de pouvoir comparer les langues acceptées (par l'UA) avec les
langues supportées (par le site) est vraiment génial !

Merci à vous deux.


Sébastien

Avatar
loufoque
Sebastien a dit le 29/03/2005 à 09:08:

Petite question complémentaire dans ce cas : est-ce que tous les
user-agent retournent forcément une langue générique quand ils
supportent différents sous-groupes. C'est ce que fait Mozilla, mais
est-ce un standard, et surtout est-il respecté ?


Aucune idée.

Sinon, il suffit sûrement de faire (non testé)
$item_tmp = strtolower(substr($matches[1][$i], 0, 2));
au lieu de
$item_tmp = strtolower($matches[1][$i]);
pour que ça fonctionne

Ainsi si l'utilisateur renvoit "fr-fr,en;q=0.9" par exemple, on retourne
"fr" et pas "en".