not - php extension soap.
Usando la variable de servidor PHP HTTP_ACCEPT_LANGUAGE (7)
¿Sabe si esto está sucediendo para todos los visitantes de su sitio desde Colombia? Los usuarios generalmente tienen la libertad de modificar la configuración de idioma de sus navegadores, o de que alguien a cargo de la computadora los modifique. Como recomienda zerkms, intente registrar las direcciones IP y sus encabezados.
Si tiene la extensión intl instalada, puede usar Locale::lookup
y Locale::acceptFromHttp
para obtener la mejor elección de idioma de la configuración del navegador del usuario y una lista de las traducciones que tiene disponibles.
Locale::acceptFromHttp($_SERVER[''HTTP_ACCEPT_LANGUAGE'']); # e.g. "en_US"
HTTP_ACCEPT_LANGUAGE
un script PHP que verifica el HTTP_ACCEPT_LANGUAGE
y carga el sitio web usando el lenguaje apropiado de los primeros dos caracteres:
$http_lang = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2);
switch ($http_lang) {
case ''en'':
$SESSION->conf[''language''] = ''english'';
break;
case ''es'':
$SESSION->conf[''language''] = ''spanish'';
break;
default:
$SESSION->conf[''language''] = $PREFS->conf[''languages''][$SESSION->conf[''language_id'']];
}
Si cambio el idioma al español en Firefox, el sitio web se carga en español bien. Sin embargo, he tenido varios informes de que la gente en Colombia ve el sitio web en inglés.
Detalles: "es-co" LCID = 9226 español (Colombia)
¿Alguien tiene alguna idea de por qué sucede esto? Pensé que esta era la mejor manera de verificar qué idiomas soportan los usuarios.
Al final me fui con esta solución:
if (isset($_SERVER[''HTTP_ACCEPT_LANGUAGE''])) {
preg_match_all(''/([a-z]{1,8}(-[a-z]{1,8})?)/s*(;/s*q/s*=/s*(1|0/.[0-9]+))?/i'', $_SERVER[''HTTP_ACCEPT_LANGUAGE''], $lang_parse);
if (count($lang_parse[1])){
$langs = array_combine($lang_parse[1], $lang_parse[4]);
foreach ($langs as $lang => $val){
if ($val === '''') $langs[$lang] = 1;
}
arsort($langs, SORT_NUMERIC);
}
foreach ($langs as $lang => $val){
if (strpos($lang,''en'')===0){
$language = ''english'';
break;
} else if (strpos($lang,''es'')===0){
$language = ''spanish'';
}
}
}
Me gustaría agradecer a AJ por los enlaces. También gracias a todos los que respondieron.
Confío en los programadores expertos que trabajan para PHP y piensan en el futuro. Aquí está mi versión de una etiqueta para el traductor de Google desplegable.
function gethttplanguage(){
$langs = array(
''en'',// default
''it'',
''dn'',
''fr'',
''es''
);
$questions = array(
"en" => "If you wish to see this site in another language click here",
"it" => "Se vuole vedere questo sito in italiano clicca qui",
"dn" => "Hvis du ønsker at se denne hjemmeside i danske klik her",
"fr" => "Si vous voulez visualiser ce site en français, cliquez ici",
"es" => "Si quieres ver este sitio en español haga clic aquí"
);
$result = array();
http_negotiate_language($langs, &$result);
return $questions[key($result)];
}
Si desea almacenar idiomas en matriz, hago esto:
preg_match_all(''/([a-z]{1,8}(-[a-z]{1,8})?)/s*(;/s*q/s*=/s*(1|0/.[0-9]+))?/i'', ''pt-br,pt;q=0.8,en-us;q=0.5,en,en-uk;q=0.3'', $lang_parse);
$langs = $lang_parse[1];
$rank = $lang_parse[4];
for($i=0; $i<count($langs); $i++){
if ($rank[$i] == NULL) $rank[$i] = $rank[$i+1];
}
Esto da salida a un array a lenguajes y otros con valores.
preg_match_all(''/([a-z]{1,8}(-[a-z]{1,8})?)/s*(;/s*q/s*=/s*(1|0/.[0-9]+))?/i'', ''pt-br,pt;q=0.8,en-us;q=0.5,en,en-uk;q=0.3'', $lang_parse);
$langs = $lang_parse[1];
$rank = $lang_parse[4];
$lang = array();
for($i=0; $i<count($langs); $i++){
$lang[$langs[$i]] = ($rank[$i] == NULL) ? $rank[$i+1] : $rank[$i];
}
esto genera una matriz como esta:
Array
(
[pt-br] => 0.8
[pt] => 0.8
[en-us] => 0.5
[en] => 0.3
[en-uk] => 0.3
)
Un método más contemporáneo sería usar http_negotiate_language()
:
$map = array("en" => "english", "es" => "spanish");
$conf_language= $map[ http_negotiate_language(array_keys($map)) ];
Si no tiene instalada la extensión http ( y no la intl ), hay otra solución en los comentarios ( nota de usuario # 86787 (noviembre de 2008; de Anonymous) ):
<?php
/*
determine which language out of an available set the user prefers most
$available_languages array with language-tag-strings (must be lowercase) that are available
$http_accept_language a HTTP_ACCEPT_LANGUAGE string (read from $_SERVER[''HTTP_ACCEPT_LANGUAGE''] if left out)
*/
function prefered_language ($available_languages,$http_accept_language="auto") {
// if $http_accept_language was left out, read it from the HTTP-Header
if ($http_accept_language == "auto") $http_accept_language = isset($_SERVER[''HTTP_ACCEPT_LANGUAGE'']) ? $_SERVER[''HTTP_ACCEPT_LANGUAGE''] : '''';
// standard for HTTP_ACCEPT_LANGUAGE is defined under
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
// pattern to find is therefore something like this:
// 1#( language-range [ ";" "q" "=" qvalue ] )
// where:
// language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
// qvalue = ( "0" [ "." 0*3DIGIT ] )
// | ( "1" [ "." 0*3("0") ] )
preg_match_all("/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?" .
"(/s*;/s*q/s*=/s*(1/.0{0,3}|0/./d{0,3}))?/s*(,|$)/i",
$http_accept_language, $hits, PREG_SET_ORDER);
// default language (in case of no hits) is the first in the array
$bestlang = $available_languages[0];
$bestqval = 0;
foreach ($hits as $arr) {
// read data from the array of this hit
$langprefix = strtolower ($arr[1]);
if (!empty($arr[3])) {
$langrange = strtolower ($arr[3]);
$language = $langprefix . "-" . $langrange;
}
else $language = $langprefix;
$qvalue = 1.0;
if (!empty($arr[5])) $qvalue = floatval($arr[5]);
// find q-maximal language
if (in_array($language,$available_languages) && ($qvalue > $bestqval)) {
$bestlang = $language;
$bestqval = $qvalue;
}
// if no direct hit, try the prefix only but decrease q-value by 10% (as http_negotiate_language does)
else if (in_array($langprefix,$available_languages) && (($qvalue*0.9) > $bestqval)) {
$bestlang = $langprefix;
$bestqval = $qvalue*0.9;
}
}
return $bestlang;
}
?>
Usaré el código de localización completo para referir el idioma, porque como zh-TW
y zh-CN
es 2 idiomas diferentes.
function httpAcceptLanguage($httpAcceptLanguage = null)
{
if ($httpAcceptLanguage == null) {
$httpAcceptLanguage = $_SERVER[''HTTP_ACCEPT_LANGUAGE''];
}
$languages = explode('','', $httpAcceptLanguage);
$result = array();
foreach ($languages as $language) {
$lang = explode('';q='', $language);
// $lang == [language, weight], default weight = 1
$result[$lang[0]] = isset($lang[1]) ? floatval($lang[1]) : 1;
}
arsort($result);
return $result;
}
// zh-TW,en-US;q=0.7,en;q=0.3
echo $_SERVER[''HTTP_ACCEPT_LANGUAGE''];
/*
Array
(
[zh-TW] => 1
[en-US] => 0.7
[en] => 0.3
)
*/
print_r(httpAcceptLanguage());
Utilicé la expresión regular de @GabrielAnderson y diseñé esta función que se comporta de acuerdo con RFC 2616 (cuando no se da un valor de calidad a un idioma, el valor predeterminado es 1).
Cuando varios idiomas comparten el mismo valor de calidad, a los más específicos se les da prioridad sobre los menos específicos. (este comportamiento no es parte del RFC que no proporciona ninguna recomendación para este caso específico)
function Get_Client_Prefered_Language ($getSortedList = false, $acceptedLanguages = false)
{
if (empty($acceptedLanguages))
$acceptedLanguages = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
// regex inspired from @GabrielAnderson on http://.com/questions/6038236/http-accept-language
preg_match_all(''/([a-z]{1,8}(-[a-z]{1,8})*)/s*(;/s*q/s*=/s*(1|0/.[0-9]+))?/i'', $acceptedLanguages, $lang_parse);
$langs = $lang_parse[1];
$ranks = $lang_parse[4];
// (create an associative array ''language'' => ''preference'')
$lang2pref = array();
for($i=0; $i<count($langs); $i++)
$lang2pref[$langs[$i]] = (float) (!empty($ranks[$i]) ? $ranks[$i] : 1);
// (comparison function for uksort)
$cmpLangs = function ($a, $b) use ($lang2pref) {
if ($lang2pref[$a] > $lang2pref[$b])
return -1;
elseif ($lang2pref[$a] < $lang2pref[$b])
return 1;
elseif (strlen($a) > strlen($b))
return -1;
elseif (strlen($a) < strlen($b))
return 1;
else
return 0;
};
// sort the languages by prefered language and by the most specific region
uksort($lang2pref, $cmpLangs);
if ($getSortedList)
return $lang2pref;
// return the first value''s key
reset($lang2pref);
return key($lang2pref);
}
Ejemplo:
print_r(Get_Client_Prefered_Language(true, ''en,en-US,en-AU;q=0.8,fr;q=0.6,en-GB;q=0.4''));
Salidas:
Array
(
[en-US] => 1
[en] => 1
[en-AU] => 0.8
[fr] => 0.6
[en-GB] => 0.4
)
Como puede observar, ''en-US'' aparece en la primera posición a pesar del hecho de que ''en'' fue el primero en la cadena dada.
Así que podrías usar esta función y simplemente reemplazar tu primera línea de código por:
$http_lang = substr(Get_Client_Prefered_Language(),0,2);