Holladiewaldfee,
Da wir gerade dabei wären: ich hab' mich jetzt mal an die Arbeit gemacht und bin mit dem Ergebnis recht zufrieden:
Na, dann will ich auch mal meine Funktion nicht vorenthalten, die ich irgendwann mal geschrieben habe ;-)
----------------------------------------------------------------
function detectlanguage($lstring, $languages)
{
# Array in Großschreibung
while(list($langkey, $langval) = each($languages))
$languages[$langkey] = strtoupper($langval);
# Einzelne Teile untersuchen
$langa = explode(",", strtoupper($lstring));
# Ausdruck auswerten
for($i=0, $j=count($langa); $i<$j; $i++)
{ $langa[$i] = Array("pattern" => trim($langa[$i]));
# Qualität ermitteln (Vorzug)
$langa[$i]["quality"] = preg_replace("/([^;]*)(;q=([0-9]{0,3}.?[0-9]*))?,?$/i","\3", $langa[$i]["pattern"]);
if(trim($langa[$i]["quality"])=="")
{ # Default: 1
$langa[$i]["quality"] = "1.0"; }
$langa[$i]["position"] = $i;
# Sprache ermitteln
$langa[$i]["languagestring"] = preg_replace("/([^;]*)(;q=[0-9]{0,3}.?[0-9]*)?,?$/i","\1", $langa[$i]["pattern"]);
if(preg_match("/[1]{1,8}(-[A-Z]{1,8}){1,}$/i", $langa[$i]["languagestring"]))
{ # Mit genauerer Spezifizierung
if(preg_match("/[2]{1,8}-[A-Z]{2}$/i", $langa[$i]["languagestring"]))
{ # Mit Nennung des Landes
$langa[$i]["contryabrev"] = preg_replace("/^([A-Z]{1,8}-)([A-Z]{2})$/i", "\2", $langa[$i]["languagestring"]);
# Land ermitteln?
if(fcms_bDETECTBROWSERCOUNTRY===true)
{ include("iso3166.cfg.php");
if(isset($aIso3166[$langa[$i]["countryabrev"]]))
$langa[$i]["country"] = $aIso3166[$langa[$i]["countryabrev"]];
}
}
else
{ # Mit Nennung des Dialekts
$langa[$i]["dialect"] = preg_replace("/^([A-Z]{1,8}-)(.*)$/i", "\2", $langa[$i]["languagestring"]); }
}
$lang = preg_replace("/^([A-Z]*)(.*)$/i", "\1", $langa[$i]["languagestring"]);
# Name der Sprache und Sprachfamilie ermitteln
if(strlen($lang)==2 && fcms_sDETECTFULLLANGUAGE===true)
{ include("iso639.cfg.php");
if(isset($aIso639[$lang]))
{ $langa[$i]["fulllanguage"] = $aIso639[$lang]["language"];
$langa[$i]["family"] = $aIso639[$lang]["langgroup"]; }
}
# Sparchkennung ist ok?
if(strlen($lang)<=8)
{ # Ja
$langa[$i]["language"] = $lang; }
else
{ # Nein
$langa[$i]["language"] = "unknown"; }
}
# Nach Priorität sortieren
if(count($langa)>1)
{ # Nur wenn mehr als eine Angabe
# Sortieren
for($i=0, $j=count($langa)-1; $i<$j; $i++)
{ for($k=$i+1, $h=count($langa); $k<$h; $k++)
{ if((floatval($langa[$i]["quality"])<floatval($langa[$k]["quality"])) || (floatval($langa[$i]["quality"])==floatval($langa[$k]["quality"]) && floatval($langa[$i]["position"])>floatval($langa[$k]["position"])))
{ # Tauschen
$temp = $langa[$i];
$langa[$i] = $langa[$k];
$langa[$k] = $temp;
}
}
}
unset($temp);
}
# Auszunutzende Sprache ermitteln
$aReturn = Array();
for($i=0, $j=count($langa); $i<$j; $i++)
{ # Zunächst versuchen, Sprache inkl. Dialekt zu finden:
if($langa[$i]["dialect"]!="")
{ if(in_array($langa[$i]["language"]."-".$langa[$i]["dialect"], $languages))
{ $aReturn["language"] = $langa[$i]["language"]."-".$langa[$i]["dialect"];
if($langa[$i]["fulllanguage"]!="")
$aReturn["fulllanguage"] = $langa[$i]["fulllanguage"];
break; }
}
# Sprache ohne Dialekt?
if(in_array($langa[$i]["language"], $languages))
{ $aReturn["language"] = $langa[$i]["language"];
if($langa[$i]["fulllanguage"]!="")
$aReturn["fulllanguage"] = $langa[$i]["fulllanguage"];
break;
}
}
# Hier könnte noch eine Funktion stehen, die bei ergebnisloser Suche versucht,
# die Sprache anhand der Sprachfamilie zuzuordnen
# Nichts gefunden?
if($aReturn["language"]=="")
$aReutrn["language"] = fcms_sDEFAULTLANGUAGE;
# Landes-Content: Immer das des erstgenannten Landes:
# Hier könnte jetzt noch eine Funktion stehen, die geographisch oder je nach Bevölkerungsgruppe
# das nächstgelegene Land ermittelt, wenn das erstgenannte nicht verfügbar ist ...
if(fcms_bDETECTBROWSERCOUNTRY===true)
{ for($i=0, $j=count($langa); $i<$j; $i++)
{ if($langa[$i]["country"]!="")
{ $aReturn["country"] = $langa[$i]["country"];
break;
}
}
}
# Zurückgeben ...
return $aReturn;
}
------------------------------------------------------------------
Zur Erklärung: Übergeben werden zwei Werte, zum einen der zu parsende String, zum anderen ein Array mit verfügbaren Sprachen.
Daneben werkelt die Funktion noch mit ein paar Konstanten rum, fcms_bDETECTBROWSERCOUNTRY, fcms_sDETECTFULLLANGUAGE und fcms_sDEFAULTLANGUAGE. Die Namen sind denke ich selbsterklärend (fcms war der Name des Projektes, für das ich die Funktion geschrieben habe).
Die beiden includes enthalten jeweils die ISO-Definitionen für Länder und Sprachen:
iso639.cfg.php ----------------------------------------------------------
http://www.oasis-open.org/cover/iso639a.html
$aIso639 = Array(
"AA" => Array("language" => "AFAR", "langgroup" => "HAMITIC"),
"AB" => Array("language" => "ABKHAZIAN", "langgroup" => "IBERO-CAUCASIAN"),
"AF" => Array("language" => "AFRIKAANS", "langgroup" => "GERMANIC"),
"AM" => Array("language" => "AMHARIC", "langgroup" => "SEMITIC"),
und so weiter
"ZA" => Array("language" => "ZHUANG", "langgroup" => "[ ]"),
"ZH" => Array("language" => "CHINESE", "langgroup" => "ASIAN"),
"ZU" => Array("language" => "ZULU", "langgroup" => "NEGRO-AFRICAN")
);
iso3166.cfg.php ---------------------------------------------------------
http://www.din.de/gremien/nas/nabd/iso3166ma/codlstp1/db_en.html
$aIso3166 = Array(
"AF" => "AFGHANISTAN",
"AL" => "ALBANIA",
"DZ" => "ALGERIA",
"AS" => "AMERICAN SAMOA",
"AD" => "ANDORRA",
usw. usf.
"YU" => "YUGOSLAVIA",
"ZM" => "ZAMBIA",
"ZW" => "ZIMBABWE"
);
-------------------------------------------------------------------------
Zurückgegeben wird ein Array, das in ["language"] die ermittelte Sprache enthält.
Was mir noch nicht ganz gefällt ist wie am Ende die Sprache ermittelt wird, da bin ich für alternative Lösungsvorschläge jederzeit offen :-)
Anregungen? Weitere Kritik?
Dem kann ich mich nur anschließen ;-)
Ciao,
Harry
(There are only 10 types of people in this world: Those who understand binary and those who don't)