10+ tips to localise your php application

0 Flares Filament.io 0 Flares ×

Localisation

Localisation involves changing various parts of application output like display of dates , time , numbers , language etc according to the standards of the geographical region of a user. Localisation is an important feature of applications that targets users across the globe and not just one region.

So here are a set of simple tips and techniques every php application can do to make itself more locale-friendly.

1. Set timezone of the application

The application should explicitly set a timezone for itself. Otherwise the timezone of the machine/server would be taken up, which may not be what the user wants.

date_default_timezone_set( 'America/Chicago' );

This should be done at the earliest in the script.

The timezone_identifiers_list() function can be used to generate a list of timezones from which the user can select. Here is a quick example :

/**
	@brief
	Get a list of timezones available for use in the application
*/
function get_timezones()
{
	$o = array();
	$t = timezone_identifiers_list();
	
	foreach($t as $a)
	{
		$t = '';
		
		//Get the time difference
		$zone = new DateTimeZone($a);
		$seconds = $zone->getOffset( new DateTime("now", $zone) );
		$hours = sprintf( "%+02d" , intval($seconds/3600));
		$minutes = sprintf( "%02d" , ($seconds%3600)/60 );
		
		$t = $a ."  [ $hours:$minutes ]" ;
		$o[$a] = $t;
	}
	ksort($o);
	
	return $o;
}

This would give you a complete list like this :

[Africa/Abidjan] => Africa/Abidjan [ +0:00 ]
[Africa/Accra] => Africa/Accra [ +0:00 ]
[Africa/Addis_Ababa] => Africa/Addis_Ababa [ +3:00 ]
[Africa/Algiers] => Africa/Algiers [ +1:00 ]
[Africa/Asmara] => Africa/Asmara [ +3:00 ]
[Africa/Bamako] => Africa/Bamako [ +0:00 ]
[Africa/Bangui] => Africa/Bangui [ +1:00 ]
[Africa/Banjul] => Africa/Banjul [ +0:00 ]
[Africa/Bissau] => Africa/Bissau [ +0:00 ]

Make a select tag dropdown out of it and let the user select his/her timezone.

2. Set the mysql timezone from the application

Applications are often hosted on servers that are in a different timezone , compared to that of the developer or the application user. Hence the timezone of mysql needs to be set properly to that of the application.

Mysql can be put in the same timezone as the application by doing :

$c = mysqli_connect($host, $username, $password);
mysqli_query($c , "SET `time_zone` = '".date('P')."'");






The php date function with P parameter gives the time difference between GMT and the applications timezone. The same is passed to mysql.

TIMESTAMP

For timestamp columns in mysql , any date-time combinations passed would be converted to correct timestamp by mysql , since mysql itself is in the correct timezone.

DATETIME

When using datetime columns , the application must convert the date-time values to UTC , and then save in mysql.
When fetching back from database they must be converted to the application's timezone.

Save to database :

$time_to_save = date('Y-m-d h:i:s');	//Current time of user that is to be saved in a datetime mysql column

$d = new DateTime($time_to_save , new DateTimeZone(date_default_timezone_get()) );

$d->setTimezone( new DateTimeZone('UTC') );	//Move to UTC

$mysql_datetime = $d->format("Y-m-d h:i:s");	//BUZZ!! Ready to save datetime value in database

Note :

1. Since the mysql timezone is being set from within the application , certain queries may give tricky output. Here is an example :

You are developing an application on your local system and have set the timezone to 'Asia/Singapore' , but your own computer's timezone is 'Asia/Kolkata'

Now inside your application you are running a certain query :

$time_schedule = "2012-04-13 10:30:00"
$query = "SELECT * FROM table WHERE time_schedule = '$time_schedule'";
//Execute the query

//some rows

When you run the same query in phpmyadmin or mysql terminal and you might get different output/rows selected.

This happens because timezone of application+mysql is different from mysql outside. You application sees different time in the database column time_schedule and phpmyadmin/mysql terminal sees a different time.

3. Set collation for database at the time of creation

The collation of the database should be set to the correct one , right in the beginning.

ALTER DATABASE db_name CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Or modify it from the Operations tab in phpmyadmin. Setting the collation and character set in the beginning ensures that all later tables, columns take up the same by default.

4. Set character set of mysql connection object

When the application is displaying non english charaters , then it must set the mysql connection's character encoding. Its simple :

mysqli_set_charset ( $c , 'UTF8' );

5. Set correct character set for htmlentities

Function htmlentities is used to echo content , that was previously provided by the user.
Prior to php 5.4 the default character encoding used is ISO-8859-1 which cannot display languages like hindi , bengali , russian etc.

$value = htmlentities($value , ENT_QUOTES , 'UTF-8');
echo $value;

Php 5.4 onwards the default encoding will be UTF-8 which will solve most problems , but still better be aware about it if your application is multilingual.

The function mb_list_encodings can be used to generate a list.

/**
	@brief
	Get the list of supported encodings using the mb_list_encodings function
*/
function get_supported_encodings()
{
	$e = mb_list_encodings();
	
	$list = array();
	
	foreach($e as $c => $val)
	{
		$list[$val] = $val;
	}
	
	return $list;
}

Would generate a list like this :

[UTF-32BE] => UTF-32BE
[UTF-32LE] => UTF-32LE
[UTF-16] => UTF-16
[UTF-16BE] => UTF-16BE
[UTF-16LE] => UTF-16LE
[UTF-8] => UTF-8
[UTF-7] => UTF-7
[UTF7-IMAP] => UTF7-IMAP
[ASCII] => ASCII
[EUC-JP] => EUC-JP
[SJIS] => SJIS

Select one and save in the database.

6. Set encoding for non html content by sending the correct headers

When echoing content like css , javascript , xml etc. set the correct encoding via the header function like this :

XML

header('Content-Type: text/xml; charset=utf-8');
//Echo rest of the xml content

Javascript

header('Content-Type: text/javascript; charset=utf-8');
//Echo rest of the javascript content

7. Set correct character set for html and xml output

HTML : This goes in the head tag of an html document

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

html5 supports :

<meta charset="utf-8">

XML : The first line of an xml document has the encoding specified

<?xml version="1.0" encoding="utf-8"?>

8. Set correct locale

Locale settings provide useful locale related settings like how to format numbers , currency symbol etc. The correct locale for the application should be setup as early as possible in the script.

setlocale(LC_ALL, 'en_US.UTF-8');

Provide the user with a list of locales to select from. Check here to learn how to do that.

9. Format numbers according to locale

When displaying numbers like plain number or currency numbers , format them with comma , decimal etc properly using function money_format. Here is a quick example :


$amount = '100000';

//Format numbers in Indian format - Lakh , Crore
setlocale(LC_MONETARY, 'en_IN');
$am = money_format('%!i', $amount);
echo $am;    //1,00,000.00

//Format in million , billion
echo "<br />";
setlocale(LC_MONETARY, 'en_US.utf8');
$am = money_format('%!i', $amount);
echo $am;    //100,000.00

10. Format display of dates

Format date display according to user format. Some different kind of date formats used are

ISO Format : 2012-04-13 (YYYY-MM-DD)
Asian countries : 13-04-2012 (DD-MM-YYYY)
USA : 04-13-2012 (MM-DD-YYYY)

Dates have to be formatted both when displaying and when being entered in a form.

Form entry : 13/04/2012 or 04/13/2012
Display : 13 Apr 2012 or Apr 13, 2012

Formatting date with strftime :

$format = '%d-%b-%Y';
$stamp = time();
$display_format = strftime( $format , $stamp);

echo $display_format; 	//Output 14-04-2012

Formatting with DateTime object :

$t = date('Y-m-d h:i:s');
$d = new DateTime($t , new DateTimeZone(date_default_timezone_get()) );
$display_format = $d->format("d-m-Y");
echo $display_format;    //15-04-2012

User should be have the option to select formats for displaying date and entering dates in forms. The user selected format , for example d-m-Y can be saved in database and reloaded next time.

11. Make the application multilingual

Finally change the language of the application to what the user wants. There are many ways to make your application multilingual. One way is to collect all label text in your application and fetch the translations from google translate service. Find out more on google.

Conclusion

Applications should be localised properly for better user experience. Applications should allow the user to select the localisation settings like timezone , locale , language , date display format etc.

Last Updated On : 14th April 2012

Subscribe to get updates delivered to your inbox

About Silver Moon

Php developer, blogger and Linux enthusiast. He can be reached at m00n.silv3r@gmail.com. Or find him on

  • blacksonic

    set correct header encoding in the webserver, just to the end of the list

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 StumbleUpon 0 Filament.io 0 Flares ×