Harry: ACCEPT_LANGUAGE

Beitrag lesen

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)

  1. A-Z ↩︎

  2. A-Z ↩︎

0 39

httpd.conf

andy
  • webserver
  1. 0
    Christoph Schnauß
    1. 0
      Christian Seiler
      1. 0
        Christoph Schnauß
        1. 0
          Christian Seiler
        2. 0
          Der Linker aus www.php4-forum.de
          1. 0
            Christoph Schnauß
            1. 0
              Christian Seiler
              1. 0

                RFC2616-konformes parsen von Accept-Language

                Christian Seiler
                • php
                1. 0
                  Orlando
                  1. 0
                    Christian Seiler
                    1. 0
                      Orlando
                      1. 0
                        Christian Seiler
                        • menschelei
                        1. 0

                          (OT) Kein spezifisches Thema ;-)

                          Orlando
                          1. 0

                            (OT) Nichts besonderes ;-)

                            Christian Seiler
                            1. 0

                              (OT) Chat-o-Rama ;-)

                              Orlando
                              1. 0

                                (OT) Ähm, ja, irgendein Titel halt ;-)

                                Christian Seiler
  2. 0
    Christian Seiler
  3. 0
    Sven Rautenberg
  4. 0
    andy
  5. 0
    andy
  6. 0
    andy
    1. 0

      ACCEPT_LANGUAGE

      Der Linker
      • php
      1. 0
        Christian Seiler
        1. 0
          Der Linker
          1. 0
            Linker
          2. 0
            Christian Seiler
            1. 0
              Der Linker
              1. 0
                Christian Seiler
                1. 0
                  Der Linker
                  1. 0
                    Christian Seiler
                    1. 0
                      Der Linker
                      1. 0
                        Christian Seiler
                        1. 0
                          Der Linker
                          1. 0
                            Christian Seiler
                            1. 0

                              Auf Wiedersehen

                              Der Linker
                              • menschelei
                        2. 0
                          Harry
                          1. 0
                            Harry
                          2. 0
                            Christian Seiler