views:

38

answers:

1

Somebody told me that example.com/en is more friendly than example.com/index.php?lang=en. How can I change my URL last part from ?lang=en to /en/?

(pd: I don't want to use gettext or any framework like zend to accomplish this)

This is how I'm internationalizing and localizing my web page:

(live example: alexchen.co.nr/)

lang.php:

<?php
function dlang($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 language() {
 // Detect HTTP_ACCEPT_LANGUAGE & HTTP_USER_AGENT.
 dlang('HTTP_ACCEPT_LANGUAGE');
 dlang('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']='zh-tw';

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

$GLOBALS['_LANG'] = array(
 'en',
 'es',
 'zh-tw',
 'zh-cn'
);
?>

session.php:

<?php
//proc all page display
include('lang.php'); //language detector
class Session
{
 var $lang;         //Username given on sign-up
 var $url;          //The page url current being viewed
 var $referrer;     //Last recorded site page viewed

 /* Class constructor */
 function Session() {
  $this->time = time();
  $this->startSession();
 }

 function cf($filename) { //function to clean a filename string so it is a valid filename
  $fp = explode('/',$filename);
  $num = count($fp);
  return $fp[$num-1];
 }

 /**
  * startSession - Performs all the actions necessary to
  * initialize this session object. Tries to determine if the
  * the user has logged in already, and sets the variables
  * accordingly. Also takes advantage of this page load to
  * update the active visitors tables.
  */
 function startSession() {
  session_start();   //Tell PHP to start the session

  /* Set referrer page */
  if(isset($_SESSION['url'])) {
   $this->referrer = $search = $this->cf($_SESSION['url']);
  }
  else {
   $this->referrer = "/";
  }

  /* Set current url */
  $this->url = $_SESSION['url'] = $this->cf($_SERVER['PHP_SELF']);

  /* Set user-determined language: */
  //set up languages array:
  //set cookie
  $langs = array('en','es','zh-tw', 'zh-cn');

  if(isset($_GET['lang'])){
   if(in_array($_GET['lang'],$langs)){
    $this->lang =  $_SESSION['lang'] = $_GET['lang'];
    setcookie("lang", $_SESSION['lang'], time() + (3600 * 24 * 30));
   }
  }
  else if(isSet($_COOKIE['lang'])) {
   $_SESSION['lang'] = $_COOKIE['lang'];
  }
  else {
   $_SESSION['lang'] = 'zh-tw';
  }
 }
};
/**
 * Initialize session object - This must be initialized before g
 * the form object because the form uses session variables,
 * which cannot be accessed unless the session has started.
 */
$session = new Session;
?>

localization.php:

    <?php
    include('session.php'); //language detector

    // determine the value of $lang_file according the one in $lang
    $languages = array('en', 'es', 'zh-tw', 'zh-cn');
    if (in_array($_SESSION['lang'], $languages)) {
        $lang_file = 'lang.'.$_SESSION['lang'].'.php';
    } else {
        $lang_file = 'lang.zh-tw.php';
    }

    // translation helper function
    function l($localization) {
     global $lang;
     return $lang[$localization]; }

    // include file for final output
     include_once 'languages/'.$lang_file;
?>
+3  A: 

ModRewrite is your friend. Throw this in your .htaccess file. You may want it to go to your session page instead of index, then redirect with PHP. Note, this only works for one page.

RewriteEngine On
RewriteBase /

# Redirect languages
RewriteRule ^(en|es|zh\-tw|zh\-cn)/?$ index.php?lang=$1 [L]
Jason McCreary
@Jason McCreary Thanks for the reply. But how do you do this? -> "You may want it to go to your session page instead of index"?
janoChen
I don't know your site structure, so I though you may want to set what language they are in the session. Do you have a multi-page site? This will simply redirect a request to a language sub-directory to index.php with the lang parameter set dynamically.
Jason McCreary
@Jason McCreary Yes my page has only as index.php, but how can I archieve the same effect for a page with more than one php file?
janoChen
Architectures vary for that. Some have physical directories for each language and files copied within each. Some utilize subdomains, Some may use mod_rewrite. It just depends. The above is specific for your current one page site. You would need a stronger `RewriteRule` for a multi-page site. It would need to strip the language and append it to the query string all while maintaining the original request.
Jason McCreary
@Marcel Korpel Weird, I tested if mod_rewrite was working in my WAMP (it works), and did exactly what you said. But the url still index.php?lang=something.
janoChen
@janoChen – 1. I'm not a participant in *this* discussion thread, so I'm not notified (I merely drove by; and yes, now I am ;-). 2. What did I say and where? You did mark this answer as appropriate, so what's the problem? If you enter e.g. `example.com/en/`, it should be internally rewritten to `example.com/index.php?lang=en`, according to this rule.
Marcel Korpel