As I mentioned in my comment above, I would recommend putting the language in the URL mainly for search engine optimization. Admittedly, it can take a bit more work to set up, but I feel the benefits outweigh the cost.
For example, I have a hotel website with English, Spanish, Chinese and French. The URL structure is like this:
/ <- Main page in English
/es/ <- Main page in Spanish
/zh/ <- Main page in Chinese
/fr/ <- Main page in French
Then for sub-pages I do similarly:
/pagename/
/es/pagename/
/zh/pagename/
/fr/pagename/
Then, this is how I redirect the other languages to the correct scripts:
# Spanish
RewriteRule ^es/(.*/)?$ $1/index.php?lang=es [NC,L]
# French
RewriteRule ^fr/(.*/)?$ $1/index.php?lang=fr [NC,L]
# Chinese
RewriteRule ^zh/(.*/)?$ $1/index.php?lang=zh [NC,L]
This works for rewriting the index.php. For other things, I specify them explicitly, usually using a "friendly" URL. For example the "thank you" page for our Contact Us page:
# Contact Us thank you page
RewriteRule ^([a-z_]+)?/?contact/thankyou$ /contact/thankyou.php?lang=$1 [L]
I also used to do the following to rewrite URLs that contained parameters, but I think doing it like this might be deprecated, not too sure (I have it in the code, but since I don't use parameters, it doesn't get triggered):
RewriteCond %{query_string} ([^=]*)=(.*)
RewriteRule ^es/(.*)$ $1/index.php?lang=es&%1=%2 [NC,L]
However, the hotel offers tours and we have a main /tours/
page and I wanted to have a friendly URL for each of the individual tours, like /tours/56/waterfall-hike
(with the tour ID and a slug from the tour name), so this handles the rewriting of the tours:
# Rewrite tours
RewriteRule ^([a-z_]+)?/?tours/([0-9]+)/reserve$ /tours/tour_reserve.php?lang=$1&id=$2 [L]
RewriteRule ^([a-z_]+)?/?tours/([0-9]+)/(.*) /tours/tour_text.php?lang=$1&id=$2&urlstr=$3 [L]
# Tours thank you page
RewriteRule ^([a-z_]+)?/?tours/thankyou$ /tours/thankyou.php?lang=$1 [L]
I just need to verify with PHP that the slug string provided is correct and if not do a 301 redirect to the correct URL based on the ID. I use this to calculate it:
function getTourURL($tour_name) {
// Transliterate non-ascii characters to ascii
$str = trim(strtolower($tour_name));
$str = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
// Do other search and replace
$searches = array(' ', '&', '/');
$replaces = array('-', 'and', '-');
$str = str_replace($searches, $replaces, $str);
// Make sure we don't have more than one dash together
$str = preg_replace("/(-{2,})/", "-", $str );
// Remove all invalid characters
$str = preg_replace("/[^A-Za-z0-9-]/", "", $str );
// Done!
return $str;
}
Then the only other difficult thing is switching languages without just redirecting them back to the home page for that language (yuck!). This is how I did it:
// First define the languages used:
$langs = array(
'en' => array(
'lang_code' => 'en_US',
'locale' => 'en_US.UTF-8',
'base_url' => '/',
'name' => 'English',
),
'es' => array(
'lang_code' => 'es_MX',
'locale' => 'es_MX.UTF-8',
'base_url' => '/es/',
'name' => 'Español',
),
'fr' => array(
'lang_code' => 'fr_FR',
'locale' => 'fr_FR.UTF-8',
'base_url' => '/fr/',
'name' => 'Français',
),
'zh' => array(
'lang_code' => 'zh_CN',
'locale' => 'zh_CN.UTF-8',
'base_url' => '/zh/',
'name' => '中国的',
),
);
define('LOCALE', $_GET['lang']);
// Then get the path to the current script after the language code
$path = (LOCALE == 'en') ? '' : LOCALE.'/';
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
$path = ltrim(str_replace('/'.LOCALE , '', $parsed_url['path']), '/');
define('REDIRECT_SCRIPT', $path);
// Then I put all the links into an array to be displayed in the menu
foreach ($langs as $lang => $arr) {
if ($lang == LOCALE) {
continue;
}
$link = (isset($lang_override[$lang]))
? $lang_override[$lang]
: $arr['base_url'] . REDIRECT_SCRIPT;
$lang_subs[] = array(
'name' => '<div class="'.$lang.'"></div> '.$langs[$lang]['name'],
'link' => $link,
'lang' => $lang,
);
}
This probably won't work for you out of the box, but should at least give you a starting point. Try a print_r($lang_subs);
to see what it contains and adapt it to your site's design.