Detect prefered language I am using this script to detect the most prefered language by the user.

function Get_Client_Prefered_Language ($getSortedList = false, $acceptedLanguages = false)
{

    if (empty($acceptedLanguages))
        $acceptedLanguages = $_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', $acceptedLanguages, $lang_parse);
    $langs = $lang_parse[1];
    $ranks = $lang_parse[4];

        // (create an associative array 'language' =&gt; 'preference')
    $lang2pref = array();
    for($i=0; $i&lt;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] &gt; $lang2pref[$b])
            return -1;
        elseif ($lang2pref[$a] &lt; $lang2pref[$b])
            return 1;
        elseif (strlen($a) &gt; strlen($b))
            return -1;
        elseif (strlen($a) &lt; 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);
}


Example:

print_r(Get_Client_Prefered_Language(true, 'en,en-US,en-AU;q=0.8,fr;q=0.6,en-GB;q=0.4'));


Output:

Array
    (
        [en-US] =&gt; 1
        [en] =&gt; 1
        [en-AU] =&gt; 0.8
        [fr] =&gt; 0.6
        [en-GB] =&gt; 0.4
    )


Is this reliable? How about performance, this script will get called many times per seconds.
The following is imho easier to read and should give you best performance.

&lt;?php

/**
 * Get a sorted list of client accepted languages.
 *
 * @staticvar array $examined
 *   Used to cache the sorted list for &lt;var&gt;$accept_languages&lt;/var&gt; strings.
 * @param boolean $list [optional]
 *   Whether to get a sorted list or the language with the highest preference, defaults to &lt;code&gt;FALSE&lt;/code&gt; and
 *   the language with the highest preference will be returned.
 * @param string $accept_languages [optional]
 *   The client submitted accept languages string in the format defined in RFC 2616.
 * @param string $default [optional]
 *   The default ISO 639-1 alpha-2 language code to use if no other language could be determined, defaults to
 *   &lt;code&gt;"en"&lt;/code&gt;.
 * @return array|string
 *   Associative array where the key is the language code or locale and the value the preference if &lt;var&gt;$list&lt;/var&gt;
 *   is set to &lt;code&gt;TRUE&lt;/code&gt;, otherwise the ISO 639-1 alpha-2 code or locale of the language with the highest
 *   preference.
 */
function get_client_preferred_language($list = false, $accept_languages = null, $default = "en") {
  static $examined = array();

  // Either use the supplied string or use the string from server input, this construct ensures highest performance
  // because a positive check is performed.
  $accept_languages || ($accept_languages = filter_input(INPUT_SERVER, "HTTP_ACCEPT_LANGUAGE", FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH));

  // Only examine this string if we haven't done so in the past.
  if (empty($examined[$accept_languages])) {
    // Prepare default fallback in our cache for this string.
    $examined[$accept_languages] = array($default =&gt; 1.0);

    // Only continue if we have a string to examine.
    if ($accept_languages) {
      // Prepare array for collecting the preferred languages.
      $languages = array();

      // Extract all languages from the accept languages string, the format is defined in RFC 2616.
      preg_match_all("/([a-z]+(?:-[a-z]+)?)\s*(?:;\s*q\s*=\s*(1|0?\.[0-9]+))?/i", $accept_languages, $matches);

      // Only go through all extracted languages if we have any.
      if (!empty($matches[1])) {
        foreach ($matches[1] as $delta =&gt; $code) {
          // Empty means highest preference.
          $languages[$code] = empty($matches[2][$delta]) ? 1.0 : (float) $matches[2][$delta];
        }

        // Sort the accepted languages by preference, if sorting fails use default.
        if (arsort($languages, SORT_NUMERIC) === true) {
          $examined[$accept_languages] = $languages;
        }
      }
    }
  }

  return $list ? $examined[$accept_languages] : array_values($examined[$accept_languages])[0];
}


// ----------------------------------------------------------------------------------------------------------------- Test


function get_client_preferred_language_test() {
  assert(array(
    "en-US" =&gt; 1.0,
    "en"    =&gt; 1.0,
    "en-AU" =&gt; 0.8,
    "fr"    =&gt; 0.6,
    "en-GB" =&gt; 0.4,
  ) === get_client_preferred_language(true, "en,en-US,en-AU;q=0.8,fr;q=0.6,en-GB;q=0.4"));
}

get_client_preferred_language_test();