views:

43

answers:

1

Hello,

I have the following code as my index.php for my multi-language website. Each available language has a subdirectory.

<?php


if (isset($_POST['URL']) && strlen($_POST['URL']) == 3) {
         header("location: ".$_POST[URL]);
}
else {

    function lixlpixel_get_env_var($Var)
    {
         if(empty($GLOBALS[$Var]))
         {
             $GLOBALS[$Var]=(!empty($GLOBALS['_SERVER'][$Var]))?
             $GLOBALS['_SERVER'][$Var] : (!empty($GLOBALS['HTTP_SERVER_VARS'][$Var])) ? $GLOBALS['HTTP_SERVER_VARS'][$Var]:'';
         }
    }

    function lixlpixel_detect_lang()
    {
         // Detect HTTP_ACCEPT_LANGUAGE & HTTP_USER_AGENT.
         lixlpixel_get_env_var('HTTP_ACCEPT_LANGUAGE');
         lixlpixel_get_env_var('HTTP_USER_AGENT');

         $_AL=strtolower($GLOBALS['HTTP_ACCEPT_LANGUAGE']);
         $_UA=strtolower($GLOBALS['HTTP_USER_AGENT']);

         // Try to detect Primary language if several languages are accepted.
         foreach($GLOBALS['_LANG'] as $K)
         {
             if(strpos($_AL, $K)===0)
             return $K;
         }

         // Try to detect any language if not yet detected.
         foreach($GLOBALS['_LANG'] as $K)
         {
             if(strpos($_AL, $K)!==false)
             return $K;
         }
         foreach($GLOBALS['_LANG'] as $K)
         {
             if(preg_match("/[[( ]{$K}[;,_-)]/",$_UA))
             return $K;
         }

         // Return default language if language is not yet detected.
         return $GLOBALS['_DLANG'];
    }

    // Define default language.
    $GLOBALS['_DLANG']='en';

    // Define all available languages.
    // WARNING: uncomment all available languages

    $GLOBALS['_LANG'] = array(
    'en', // english.
    'es', // spanish.
    'fr', // french.
    );

    /*
    $GLOBALS['_LANG'] = array(
    'af', // afrikaans.
    'ar', // arabic.
    'bg', // bulgarian.
    'ca', // catalan.
    'cs', // czech.
    'da', // danish.
    'de', // german.
    'el', // greek.
    'en', // english.
    'es', // spanish.
    'et', // estonian.
    'fi', // finnish.
    'fr', // french.
    'gl', // galician.
    'he', // hebrew.
    'hi', // hindi.
    'hr', // croatian.
    'hu', // hungarian.
    'id', // indonesian.
    'it', // italian.
    'ja', // japanese.
    'ko', // korean.
    'ka', // georgian.
    'lt', // lithuanian.
    'lv', // latvian.
    'ms', // malay.
    'nl', // dutch.
    'no', // norwegian.
    'pl', // polish.
    'pt', // portuguese.
    'ro', // romanian.
    'ru', // russian.
    'sk', // slovak.
    'sl', // slovenian.
    'sq', // albanian.
    'sr', // serbian.
    'sv', // swedish.
    'th', // thai.
    'tr', // turkish.
    'uk', // ukrainian.
    'zh' // chinese.
    );
    */

    // Redirect to the correct location.


    header('location: /'.lixlpixel_detect_lang());
    //header('location: http://www.your_site.com/index_'.lixlpixel_detect_lang().'.php'); // Example Implementation
    echo 'The Language detected is: '.lixlpixel_detect_lang(); // For Demonstration

}

?>

The problem is that although in user browsers this works perfectly, with search engines (like Googlebot) the following error is thrown:

    <br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  Cannot modify header information - headers already sent by (output started at /index.php:41) in <b>/index.php</b> on line <b>110</b><br />
<br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  preg_match() [<a href='function.preg-match'>function.preg-match</a>]: Compilation failed: range out of order in character class at offset 12 in <b>/index.php</b> on line <b>41</b><br />
The Language detected is: en

I have tried error handling but I'm not a PHP programmer, I'm a CF progammer, so I really needs some help!

+2  A: 

Inside a character class, the - denotes a range. In this case _-) in [;,_-)] is interpreted as range (every character between _ and ) inclusive). But _ (0x95) is after ) (0x28), so _-) is an invalid range.

If you mean the three individual characters _, -, and ), escape the -:

[;,_\-)]

Apart from that, Accept-Language is a list of weighted values (see the q parameter). That means just the occurrence of a particular language tag does not necessarily mean that it’s the most preferred language. There might be languages that are more preferred (higher q value) or even not accepted at all (i.e. q=0).

So instead of just looking for the occurrence of a particular language tag, you should better parse the list and find the best match of preferred languages and available languages.

Gumbo
Many, many, many, many thanks for this. You solved the error and the code still works! HERO!!!!!!
harryfear