PHP
  Home arrow PHP arrow Simple Localisation with PHP
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

Simple Localisation with PHP
By: Emmanuel M. Decarie
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 4
    2003-07-14

    Table of Contents:

    Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    In this article Emmanual shows us how to localise our PHP-driven websites...
    • Simple Localization with PHP
    • Listing setstring
    • How it Works
    • Extending setstring
    • Versions History
    • Requirements
    • Download

    On PHP DevCenter, Adam Trachtenberg and Joao Prado Maia have described interesting ways to localize web sites with PHP. In this article I've offered another alternative, which should be easy for non-programmers to use. We will take advantage of the user function setstring function:

    setstring ( $lang, $string, [$lang, $string])

    Here's a working example of a login page in French and English, which could easily be turned into a template:

    Example 1: The Login Page (try me!)

    Français | English | Logoff

    Enregistrement requis

    Nom de login:

    Mot de passe:

    The HTML Source of the Login Page

    <? include_once ("./setstring.inc") ?>
    <?= "<a href='" . $PHP_SELF . "?lang=fr'>Français</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?lang=en'>English</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?logoff=1'>Logoff</a>" ?>
    <form method="post" action="<?=$PHP_SELF?>">
        <p>
            <b><?=setstring ( 'fr', 'Enregistrement requis', 'en', 'Login required')?></b>
        </p>
        <p>
            <?=setstring ('fr', 'Nom de login:', 'en', 'Login')?><br><input type="text" name="uid" size="8">
        </p>
        <p>
            <?=setstring ( 'fr', 'Mot de passe:', 'en', 'Password')?><br><input type="password" name="pwd" size="8">
        </p>
        <p>
            <input type="submit" name="processlogin" value=" <?= setstring ( 'fr', 'Confirmer', 'en', 'Submit') ?> ">
        </p>
    </form>

    As you can see, this simple function can be useful when you don't want a web interface for non-programmers to manage different language versions (which the two articles cited above imply). This is ideal in situations where you don't need to display a large amount of content, as is the case of the login page example. (Well, this is not completely accurate as we will see later.)

    The setstring function is easy to manage. It uses session variables to maintain the language preference of the user, and possibly a cookie to maintain state after the session finishes. Let's look at the code now, and I'll explain it in detail below.

    The setstring Listing

     1  ####################################
    2   # setstring.inc - Version 1.0 - December 19 2002
    3   # Copyright: Emmanuel M. Decarie - emm@scriptdigital.com - http://scriptdigital.com
    4   # BSD License
    5   # READ ME: http://www.scriptdigital.com/divers/phplocalization.html
    6   # $Date: 2002/12/19 19:41:45 $ - $RCSfile: setstring.inc,v $ - $Revision: 1.1.1.1 $
    7   ####################################
    8   
    9   # start the session
    10   session_start ();
    11   
    12   # Set the default language.
    13   $defaultlanguage = "fr";
    14   
    15   # Set to 1 if you want to use a cookie.
    16   $use_cookie = 1;
    17   
    18   # Cookie expiration.
    19   $expire_cookie = 3600 * 24 * 2; /* 2 days */
    20   
    21   
    22   # Set $getlang to the requested key for the language if a GET arg 'lang' exists.
    23   $getlang = $_GET['lang'];
    24   
    25   # Set a cookie to the GET arg 'lang' if it exists.
    26   # Set the SESSION key 'lang' to the 'lang' value of the cookie if it exits.
    27   if ( $use_cookie == 1 ) {
    28   if ( isset ($getlang) ) {
    29   setcookie ('lang', $getlang, expire_cookie);
    30   }
    31  
    32   if ( isset ($_COOKIE['lang']) ) {
    33   $_SESSION['lang'] = $_COOKIE['lang'];
    34   }
    35   }
    36   
    37   # Destroy session and cookie.
    38   if ( isset ($_GET['logoff']) ) {
    39   session_destroy ();
    40   if ( $use_cookie == 1 ) { setcookie ('lang',$getlang, -3600); }
    41   header ("Location: http://" . $_SERVER['HTTP_HOST'] . "/" . $PHP_SELF);
    42   }
    43   
    44   # The main routine.
    45   # It expect an array for argument: ('lang1', 'string', 'lang2', string').
    46   function setstring () {
    47   global $defaultlanguage;
    48   global $getlang;
    49   $lang = $_SESSION['lang'];
    50   $args = func_get_args ();
    51  
    52   # A newcomer.
    53   if ( !isset ($lang) ) {
    54   session_register ('lang');
    55   $lang = $defaultlanguage;
    56   }
    57  
    58   # give $_GET['lang'] the choice to set $lang 
    59   if (  isset ($getlang) ) { 
    60   $lang = $getlang;
    61   $_SESSION['lang'] = $lang;
    62  
    63   }
    64  
    65   # Now $lang have been set either by $languagedefautl, $getlang, or $_SESSION['lang'].
    66   # Loop in the language array and return $string if $lang is found.
    67   if ( count ($args) ) {
    68   if ( in_array ($lang, $args) ) {
    69   for ($i = 0; $i < count ($args); $i++) {
    70   if ( $args[$i] == $lang ) {
    71   return $args[$i + 1];
    72   }
    73   }
    74   }
    75   }
    76   return "";
    77   }

    How it Works

    Before looking at the script itself, it is important to note that you'll need to put your include statement (the include ("./setstring.inc") call) before any HTML output. This is because setstring can use cookies; see setcookie in the PHP manual for details.

    At the beginning of the script (lines: 12-19) we set the configurations for $defaultlanguage, $use_cookie and $expirecookie. The value of the $defaultlanguage is for newcomers that don't have a cookie or that didn't set the language by clicking on a link. The value of the default language can be anything, as the names of the languages. You can use something like this if you like:

    $defaultlanguage = "schtroumph"
    <?= setstring ('schtroumph', 'Quelle schtroumphe est-il ?', 'klingon', "'arlogh Qoylu'pu'?") ?>

    Don't forget to escape your quotes inside the string returned by the function. This will not work: ('klingon', ''arlogh Qoylu'pu'?') but this will: 'klingon', ('\'arlogh Qoylu\'pu\'?'). You can also change single quote to double quotes as in the example above.

    Also, don't forget to use HTML entities to escape non-ASCII text. If you use languages like Arabic, Chinese or Hebrew, and depending if you use UTF-8 for text encoding or another variety of encoding that is not based on Unicode (like, for example, GB-2312 for Simplified Chinese), you can use directly this encoding with the setstring function. But you have to set the http-equiv in the <meta> tag like this:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    or 

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    You set $use_cookie to 1 if you want your users to keep their language setting after the session finishes, and set $expirecookie to the number of seconds you want the cookie to last. In the example, $expirecookie is set to expire in 2 days.

    The language which the function returns is determined by order of priority:

    • (1) the value of the lang argument in the GET request (lines: 23, 58)

      You set the 'lang' value in the GET request by a link like this so that the page will point to itself:
      <?= "<a href='" . $PHP_SELF . "?lang=fr'>Français</a>" ?>

      And will look like this after PHP has processed it:
      <a href='/divers/phplocalization.html?lang=fr'>Français</a>

      If the 'lang' value in the GET request is set and if $use_cookie == 1, we set a cookie for the 'lang' value.

    • (2) the value of the lang keyword for a cookie set previously by setstring (line: 32)

      This was set in (1) if the user has clicked on a link with '?lang=$lang'.

    • (3) the global value $defaultlanguage (lines: 13, 55)

      If nothing happened at (1) or (2), use the $defaultlanguage value to set the language.

    When the $lang keyword is found, setstring loop in the array that was pass to it (lines: 65-75) and returns the value of the element (which is the $string parameter) after the element that matches the value of $lang. Here's a snippet of code that illustrate the above.

    $lang = 'en';
    setstring ('fr', 'Allo', 'en', 'Hello');
    for ($i = 0; $i < count ($args); $i++) {
        if ( $args[$i] == $lang ) {                 # $lang == 'en'
            return $args[$i + 1];                   # return 'Hello'
        }

    Extending setstring

    If you have repetitive text, you could use setstring with constants, and here's how to do it for the login example above. First, create a file for each language and define the same constants.

    french.inc

    <?
    ####################################
    # french.inc
    # $Date$ - $RCSfile$ - $Revision$
    ####################################
    define ('LOGIN_REQUIRED', "Enregistrement requis");
    define ('LOGIN', "Nom de login");
    define ('PASSWORD', "Mot de passe");
    ?>

    english.inc

    <?
    ####################################
    # english.inc
    # $Date$ - $RCSfile$ - $Revision$
    ####################################
    define ('LOGIN_REQUIRED', "Login Required");
    define ('LOGIN', "Login");
    define ('PASSWORD', "Password");
    ?>

    Then, you just have to use setstring once to build different languages versions. Here, we use setstring to pass the right language file to include.

    Example 2: The Login Page

    <? include_once ("./setstring.inc") ?>
    <? include ( setstring ( 'fr', './french.inc', 'en', './english.inc') )?>
    <?= "<a href='" . $PHP_SELF . "?lang=fr'>Français</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?lang=en'>English</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?logoff=1'>Logoff</a>" ?>
    <form method="post" action="<?=$PHP_SELF?>">
    <p>
    <b><?=LOGIN_REQUIRED?></b>
    </p>
    <p>
    <?=LOGIN?><br><input type="text" name="uid" size="8">
    </p>
    <p>
    <?=PASSWORD?><br><input type="password" name="pwd" size="8">
    </p>
    <p>
    <input type="submit" name="processlogin" value=" <?= SUBMIT ?> ">
    </p>
    </form>

    If you have a lot of text you can use an include function with setstring. You create a file for each language as above, and then use the include function:

    Example 3: include and setstring

    <? include_once ("./setstring.inc") ?>
    <?= "<a href='" . $PHP_SELF . "?lang=fr'>Français</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?lang=en'>English</a>" ?> |
    <?= "<a href='" . $PHP_SELF . "?logoff=1'>Logoff</a>" ?>
    <? include ( setstring ( 'fr', './filefrench.inc', 'en', './fileenglish.inc') )?>

    Versions History

    Version 1.0

    First release: December 19 2002.
    Open Source (BSD license).
    A big thanks to Hans Zaunere, Jim Byrne, Jaz-Michael King, and Deke Smith for reviewing this text.

    Requirements

    PHP greater than 4.1.x

    Download

    Save this page to your disk as "setstring.inc". (This link will open a new window.)

    Notes

    Internationalization and Localization with PHP
    by Adam Trachtenberg
    http://www.onlamp.com/pub/a/php/2002/11/28/php_i18n.html?page=1

    Gettext
    by Joao Prado Maia
    http://www.onlamp.com/pub/a/php/2002/06/13/php.html


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

    More PHP Articles
    More By Emmanuel M. Decarie

     

    IBM® developerWorks developerWorks - FREE Tools!


    Be the first to hear about i5/OS V6R1!

    Hold your calendar on January 30, 2008 for this free webcast on the new i5/OS. Rational's Enterprise Modernization products will be discussed at this webcast as they help to drive the application development environment for this new System i OS. <br /> And learn how i5/OS will take you to the next step of efficient, resilient business processing. You will hear about the new i5/OS capabilities as it will be the most significant i5/OS release in years. If you cannot join the webcast on 1/30/08 you can still use this link to listen to the replay.<br />
    FREE! Go There Now!


    IBM – Taking Web 2.0 to Work

    You'll get answers to many questions and more from David Barnes, Lead Evangelist for IBM Emerging Internet Technologies. David will discuss aspects of Web 2.0 that bring value to corporations, academia, and government. He'll also discuss IBM's vision around Web 2.0, including the importance of remixability and consumability. The discussion will culminate with examples of various IBM Software Group solutions you can use to get ahead of the Web 2.0 adoption curve.
    FREE! Go There Now!


    NEW! Addressing software-as-a-service challenges using Tivoli security and WebSphere solutions

    Building a software-as-a-service solution requires addressing a few key technical challenges. In this webcast, we'll focus on the role of IBM Tivoli Directory Server and WebSphere Portlet Factory in creating a Software as a Service solution. We will demonstrate how to use Tivoli Directory Server to prevent the user population of one tenant from accessing the virtual portal and portlet components of another tenant. We will also use the dynamic profile capability of WebSphere Portlet Factory to create multiple highly customized applications from one code base.
    FREE! Go There Now!


    NEW! Evaluate Rational Business Developer V7.1

    Visit IBM developerWorks to download a free trial version of IBM Rational Business Developer V7.1. Rational Business Developer offers rapid and simplified development of business applications and services through Enterprise Generation Language (EGL) tools, generating Java or mainframe solutions while shielding developers from technical complexities.
    FREE! Go There Now!


    NEW! Hello World: Monitor a simple business process using WebSphere Business Monitor V6.0.2

    This tutorial shows new users of IBM WebSphere Business Monitor Version 6.0.2 how to perform the "Hello World" equivalent for monitoring business process applications. It is intended to help you get familiar with the capabilities of the product.
    FREE! Go There Now!


    NEW! Info 2.0: Harnessing the power of Web 2.0 and Enterprise Mashups

    Listen to this webcast to get an overview of Info 2.0 and a technical demo of how to quickly build an enterprise mashup. IBM's Info 2.0 technology leverages emerging Web 2.0 technologies such as mashups, feeds, AJAX, and JSON in order to simplify assembly of information using feeds and services. Come learn about the technical elements of Info 2.0 including the Feed Generation framework, Mashup Engine, and mashup assembly components. Learn how to pull information from databases, departmental information, and the Web to create mashups critical to your company’s success. We will also discuss best practices to help you get started.
    FREE! Go There Now!


    NEW! Integrating XML into Your Enterprise Using Data Federation

    XML has become a common way of storing business data as flat files and many data server vendors including IBM have provided ways to store this data within relational database systems. Increasingly collections of XML files are accessed like databases using an xQuery and other XML standard mechanisms. Businesses find the need to combine the traditional tabular structured data with XML formatted data. In this webcast, you’ll learn about IBM’s WebSphere Federation Server technology, which provides users with the ability to integrate these two data formats.
    FREE! Go There Now!


    NEW! Run your first CICS application on a PC using TXSeries for Windows

    Learn the basics of the IBM Customer Information Control System (CICS). With a hands-on exercise, learn how to get your first CICS application up and running on your desktop using TXSeries V6.1 for Windows. The tutorial shows you how to download and install a free trial version of TXSeries V6.1.
    FREE! Go There Now!


    NEW! Webcast: Accelerating Software Innovation with System z

    Attend this launch webcast with Scott Hebner, Vice President of IBM Rational Marketing and Strategy, where he will overview Rational’s new offerings and programs to help customers accelerate software innovation on System z. He will discuss how these solutions help organizations extend their core business processes toward modern architectures such as SOA and web technologies to deliver business improvements that stand the test of time.
    FREE! Go There Now!


    NEW! Webcast: Quickly provide customized, integrated user interfaces with Lotus Notes 8

    IBM Lotus Notes 8 provides a wide range of developers the ability to provide customized, integrated user interfaces via composite applications and via custom sidebar and toolbar plug-ins. This webcast provides you with tips and techniques to use with out-of-the-box capabilities of Lotus Notes 8, and survey how you can share useful components within your own company and within a larger community.
    FREE! Go There Now!



    All FREE IBM® developerWorks Tools!

    PHP ARTICLES

    - Making Usage Statistics in PHP
    - Installing PHP under Windows: Further Config...
    - File Version Management in PHP
    - Statistical View of Data in a Clustered Bar ...
    - Creating a Multi-File Upload Script in PHP
    - Executing Microsoft SQL Server Stored Proced...
    - Code 10x More Efficiently Using Data Access ...
    - A Few Tips for Speeding Up PHP Code
    - The Modular Web Page
    - Quick E-Commerce with PHP and PayPal
    - Regression Testing With JMeter
    - Building an Iterator with PHP
    - PHP Frontend to ImageMagick
    - Using PEAR's mimeDecode Module
    - Incoming Mail and PHP







    © 2003-2010 by Developer Shed. All rights reserved. DS Cluster 9 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek