Water reflections on a roof

#Snippet

Accept-Language

Das folgende Snippet parst den Accept-Language HTTP-Header und liefert ein Array mit den Sprachen.

Das zurückgelieferte Array enthält den Vorzugsgrad der Sprache als Key, der Value ist das Kürzel der jeweiligen Sprache. Das Array ist absteigend von der bevorzugten zu der am wenigsten bevorzugten Sprache sortiert.

/**
 * Parse the Accept-Language HTTP header sent by the browser. It
 * will return an array with the languages the user accepts, sorted
 * from most preferred to least preferred.
 *
 * @return  Array: key is the importance, value is the language code.
 */
function parseAcceptLanguage() {
  $ayLang = array();
  $aySeen = array();
  if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    foreach(explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']) as $llang) {
      preg_match("#^(.*?)([-_].*?)?(\;q\=(.*))?$#i", $llang, $ayM);
      $q = isset($ayM[4]) ? $ayM[4] : '1.0';
      $lang = strtolower(trim($ayM[1]));
      if(!in_array($lang, $aySeen)) {
        $ayLang[$q] = $lang;
        $aySeen[] = $lang;
      }
    }
    uksort($ayLang, create_function('$a,$b','return ($a>$b) ? -1 : 1;'));
  }
  return $ayLang;
}

Im Prinzip braucht man jetzt nichts weiter mehr zu machen, als das Array in der Reihenfolge zu durchlaufen, bis man eine Sprachkennung findet, die man auf der Seite unterstützt.

RFC-2047-Wandler

Dieser Codeschnippsel wandelt einen String nach RFC-2047 um.

Die RFC-2047 wird verwendet, um Umlaute in Mail- und News-Headern darzustellen. Die folgenden beiden Funktionen wandeln einen String entsprechend um.

/**
 * Converts the passed string to an RFC-2047 encoded word.
 * 
 * The string will always be converted. This function also takes care of
 * proper wrapping.
 *
 * @param   $str      String to be encoded
 * @param   $encode   The character set to be used (e.g. "ISO-8859-1")
 * @return  Converted string
 */
function rfc2047conv($str, $encode) {
  if(!strlen($str)) return "";
  $result  = "=?${encode}?Q?";
  $intro   = strlen($result);
  $charcnt = $intro;
  for($ix=0; $ix < strlen($str); $ix++) {
    if($charcnt > 70) {
      $result .= "?=\r\n =?${encode}Q?";
      $charcnt = $intro;
    }
    $chr = $str{$ix};
    if($chr=='?' || $chr=='_' || $chr=='=' || $chr<' ' || $chr>'~' ) {
      $result .= sprintf("=%02X", ord($chr));
      $charcnt+=3;
    }else {
      $result .= ($chr==' ' ? "_" : $chr);
      $charcnt++;
    }
  }
  $result .= "?=";
  return $result;
}

/**
 * This function will only encode the shortest required section of
 * the string. If there are no characters in the string that need to
 * be encoded, the string will be returned unaltered.
 * 
 * WARNING: Even though most mail clients can handle the result, it
 * is not RFC compliant!
 *
 * @param   $str      String to be encoded
 * @param   $encode   The character set to be used
 * @return  Converted string
 */
function rfc2047short($str, $encode) {
  return preg_replace(
    '/^([ -~]*)(.*?)([ -~]*)$/e',
    '"$1".rfc2047conv("$2",$encode)."$3"',
    $str
  );
}