devxlogo

Base Concepts of Internationalization in PHP

Base Concepts of Internationalization in PHP

f you develop Web applications that have an international target audience, then you have to take internationalization into account—a process that includes avoiding date/time or currency confusions and delivering all text pertinent to the user interface in the user’s preferred language. Applications that can grow international traffic and improve revenue must respect their clients’ needs.

PHP comes with a set of PEARs that support internationalization from several different angles and levels of complexity. The I18N PEAR presented in this article offers the core internationalization support for your PHP applications. You will see how to:

  • Download and install the I18N PEAR
  • Internationalize numbers
  • Internationalize currencies
  • Internationalize dates and times

A Brief Introduction to Internationalization for Web Applications
Internationalization is a programming technique that you use to adapt an application for use in an international context. In an internationalized application, important information, such as currency values, numbers, times and dates, specific symbols, native characters, directions, and so on, get rendered in the format and language common to each user’s expectations. Internationalized applications try to detect the user’s locale (the user’s country and preferred language) by querying the user’s browser, which passes a combined “language and country code” that uses ISO-standardized values to specify the “default” country and language. For example, people in the United States who prefer English typically have their browsers set to pass an en_US (English, United States) code, while French-speaking people in France typically have their browser set to pass the code fr_FR.

Browsers pass the two values with each request as a single string concatenated with an underscore, as shown in the previous examples. Applications are responsible for splitting the string into the separate language and country codes. After doing that, the application can use the codes to apply a format corresponding to that request’s language and country codes.

Alternatively, internationalized applications offer users the ability to choose their locale—often by placing a set of flags somewhere on the page that reflect the countries for which specifically formatted or translated information is available, or providing a list of countries and languages from which users can select a preference.

One way to achieve internationalization is to store locale-dependent resources in external files that contain the pre-formatted or translated resources—one for each supported locale—and then have the application load resources from the appropriate file based on either the user’s browser locale settings, or the user’s locale selection. However, when language is not a problem, and the application simply needs to show currency values, numbers, dates, and times in a locale-specific way, developers can use a simpler internationalization technique, storing a single “standard” value, and passing that value, along with the locale, to a library that returns a version formatted appropriately for the specified locale.

This article explains the latter approach. In PHP, you can use the I18N PEAR library to format locale-dependent values.

Download and Install the I18N PEAR Package
You can download and install the I18N PEAR as follows (note that the latest beta release of this package is 0.8.6):

   >> pear install I18N-0.8.6

Class Trees for Package I18N
This PEAR comes with the following class trees:

  • Root class I18N_Common
    • I18N_Common
    • I18N_Country
      • I18N_Language
  • Root class I18N_Format
    • I18N_Format
    • I18N_DateTime
      • I18N_Number
        • I18N_Currency

The rest of this article explains how to use these classes.

Using the I18N_Country Class
You use the I18N_Country class to determine the country name from a country code. The class has these two methods:

  • void getName([: $code = ”]): Returns the name of the country using the country code passed by the string argument $code.
  • void isValidCode(mixed $code): Check whether the country code passed by the $code argument is valid.

Here’s a simple example that shows how to use the methods of the I18N_Country class:

   ';   print '

Countries codes

'; foreach( $countries_codes as $code ) { //Create an instance of the I18N_Country class $country = new I18N_Country (); print ''.$code.' -->'; //Check if $code is a valid code if($country->isValidCode($code)) { //Return name of the country for country code passed print ( $country->getName($code) ).'
'; } else { print ''; print ( ' This is not a valid code!!!
' ); } } ?>

The output of this example is:

   Countries codes   AF -->AFGHANISTAN   AQ -->ANTARCTICA   BD -->BANGLADESH   MB --> This is not a valid code!!!    DE -->GERMANY   FR -->FRANCE   HR -->CROATIA (local name: Hrvatska)   JP -->JAPAN   IS -->ICELAND   IT -->ITALY   MU -->MAURITIUS   RO -->ROMANIA   US -->UNITED STATES   JA --> This is not a valid code!!! 

Using the I18N_Language Class
You use the I18N_Language class to determine the language name from a specified language code using the getName method:

  • void getName([: $code = ”], : 1): Returns the name of the language using the language code passed by the string argument $code. The 1 parameter represents the string language code.

Here’s a simple application that uses the I18N_Language class:

   ';   print '

Language codes

'; foreach( $language_codes as $code ) { //Create an instance of the I18N_Language class $language = new I18N_Language (); print ''. $code.' -->'; //Return name of the language for language code passed print ($language->getName($code)).'
'; } ?>

The output of this example is:

   Language codes   af -->Afrikaans   da -->Danish   es -->Spanish   de -->German   fr -->French   ja -->Japanese   it -->Italian   mn -->Mongolian   ro -->Romanian   en -->English

The combination of the user’s country and language give you the locale.

Using the I18N_Number Class
This class localizes numbers. It formats a given number using either a default or defined format. The format function has the following prototype:

  • string format(mixed $number, [mixed $format = null]): Returns the formatted $number according to the format specified by the $format argument, which takes one of the values: I18N_NUMBER_FLOAT, I18N_NUMBER_INTEGER or a custom format created using the setFormat method described next. If the $format argument is missing then the default value is I18N_NUMBER_FLOAT.

The class inherits its next two functions from the I18N_Format class:

  • int setFormat(string $format): Define a custom format given by the $format argument.
  • void getFormat(): Returns a format identifier that can be passed to the format method for specifying the number’s format type.

The following example sets a custom format and returns the formatted number and the associated format identifier:

    '. $number->format( 999999,1 ) ).'
'; //Print in a custom format the pi value print( 'custom --> '.$number->format( 999999,$number->setFormat( array(5,'$','#'))) ).'
'; //Print the custom format id print ( 'custom format id --> '.$number->getFormat() ).'
'; //Print in the integer format the pi value print( 'integer --> '.$number->format( 999999,2 ) ).'
'; ?>

The result is:

   float --> 999,999.000   custom --> 999#999$00000   custom format id --> 100   integer --> 999,999

Listing 1 shows a longer example that formats a given number for different languages. The listing sets up a simple input page where users can enter a number. It then formats the number appropriately for a range of different language codes. Figure 1 shows a screenshot of the simple interface.

 
Figure 1. Simple Numeric-Entry Interface: When a user enters a numeric value and clicks Send, the application displays the entered value in a variety of locale-specific formats.

For example, if a user entered 123456, the program would produce results like these:

Float format:

   es_ES --> 123.456,000   nl_NL --> 123 456,000   de_DE --> 123.456,000   fr_FR --> 123 456,000   it_IT --> 123.456,000   en_US --> 123,456.000      The float format id is : 1

Integer format:

   es_ES --> 123.456   nl_NL --> 123 456   de_DE --> 123.456   fr_FR --> 123 456   it_IT --> 123.456   en_US --> 123,456      The integer format id is : 2

Custom format:

   es_ES --> 123*456&00   nl_NL --> 123*456&00   de_DE --> 123*456&00   fr_FR --> 123*456&00   it_IT --> 123*456&00   en_US --> 123*456&00      The custom format id is : 100

Using the I18N_Currency class
You use the I18N_Currency class to localize currency values and format specified amounts using a default or defined format. The format function has the next prototype:

  • void format(mixed $amount, [mixed $format = I18N_CURRENCY_LOCAL]): Returns the $amount formatted according to the specified format, which can be either I18N_CURRENCY_LOCAL, or I18N_CURRENCY_INTERNATIONAL, or can take a custom format created using the setFormat method described next. If the $format argument is missing, the default value is I18N_CURRENCY_LOCAL.

The I18N_Currency class inherits the setFormat and getFormat methods from the I18N_Format class (see the preceding section, “Using the I18N_Number Class”).

Here’s a short sample application that formats a given amount for different languages. This example uses a simple data-entry interface identical to the previous example (see Figure 1), and formats the user’s entry appropriately for several different locales. You can download the complete code; the example below shows only the pertinent PHP code in the page:

   ';      print '

Currency format

'; foreach( $languages as $lang ) { //Create an instance of the I18N_Currency class $currency = new I18N_Currency( $lang ); print ''.$lang.'
'; //Print the $currency variable into the currency local format print 'Currency Local --> '.$currency->format($get_sum).'
'; //Print the $currency variable into the currency international format print 'Currency International --> '.$currency->format( $get_sum,2).'

'; } } ?>

The output of this example is:

Currency format

   es_ES      Currency Local --> 123.456,00 €      Currency International --> 123.456,00 Eur            nl_NL      Currency Local --> 123.456,00 €      Currency International --> 123.456,00 Eur            de_DE      Currency Local --> 123.456,00 €      Currency International --> 123.456,00 Eur            fr_FR      Currency Local --> 123.456,00 €      Currency International --> 123.456,00 Eur            it_IT      Currency Local --> 123.456,00 €      Currency International --> 123.456,00 Eur            en_US      Currency Local --> $123,456.00      Currency International --> $US 123,456.00

Using the I18N_DateTime Class
Localizing dates and times follows a similar pattern, using the I18N_DateTime class. The class formats dates and times according to a specified locale and format mode, which may be a custom format. The prototypes of the most commonly-used methods are:

  • string format([int $timestamp = null], [int $format = null]): Returns the formatted timestamp according to the specified format ($format). The $format argument takes one of these values: I18N_DATETIME_SHORT, I18N_DATETIME_DEFAULT, I18N_DATETIME_MEDIUM, I18N_DATETIME_LONG, I18N_DATETIME_FULL.
  • string formatFull([int $timestamp = null]): Returns a fully-formatted timestamp (equivalent to: format($timestamp , I18N_DATETIME_FULL).
  • string formatLong([int $timestamp = null]): Returns a long-formatted timestamp (equivalent to: format($timestamp , I18N_DATETIME_LONG).
  • string formatShort([int $timestamp = null]): Returns a short-formatted timestamp (equivalent to: format($timestamp , I18N_DATETIME_SHORT).
  • string formatDate([int $timestamp = null], [int $format = null]): Returns only the formatted date. If the $format argument is missing the method uses the default format for the current locale.

Other included self-explanatory methods are: formatDateFull, formatDateLong, and formatDateShort. You can format just the time portion of a date/time value using:

 
Figure 2. Date/Time Entry Interface: This example uses dropdowns to let users select a date and time, which it then displays appropriately for several different locales.
  • string formatTime([int $timestamp = null], [int $format = null]): This function returns only the formatted time. If the $format argument is missing then the function uses the default format for the current locale.

Similar to dates, other available methods are formatTimeFull, formatTimeLong, and formatTimeShort.

The application in Listing 2 formats a timestamp (date + time). Again, the application sets up a simple data-entry interface (see Figure 2), and shows the output for several different locales.

The output of this application is:

   es_ES   Date and Time format   format: 07-sep-1980 11:20:30      formatFull: domingo, 07 de septiembre de 1980 11:20 EET +0200      formatLong: 07 septiembre 1980 11:20:30 EET +0200      formatShort: 07/09/80 11:20      Only Date format   formatDate: 07-sep-1980      formatDateFull: domingo, 07 de septiembre de 1980      formatDateLong: 07 septiembre 1980      formatDateShort: 07/09/80      Only Time format   formatTime: 11:20:30      formatTimeFull: 11:20 EET +0200      formatTimeLong: 11:20:30 EET +0200      formatTimeLong: 11:20      ===============================================================      fr_FR   Date and Time format   format: 07-sep-1980 11:20:30      formatFull: dimanche, 07 de septembre de 1980 11:20 EET +0200      formatLong: 07 septembre 1980 11:20:30 EET +0200      formatShort: 07/09/80 11:20      Only Date format   formatDate: 07-sep-1980      formatDateFull: dimanche, 07 de septembre de 1980      formatDateLong: 07 septembre 1980      formatDateShort: 07/09/80      Only Time format   formatTime: 11:20:30      formatTimeFull: 11:20 EET +0200      formatTimeLong: 11:20:30 EET +0200      formatTimeLong: 11:20      ===============================================================      it_IT   Date and Time format   format: 07 Set 1980 11:20:30      formatFull: Domenica 07 Settembre 1980 11:20      formatLong: 07 Settembre 1980 11:20:30 EET +0200      formatShort: 07/09/80 11:20      Only Date format   formatDate: 07 Set 1980      formatDateFull: Domenica 07 Settembre 1980      formatDateLong: 07 Settembre 1980      formatDateShort: 07/09/80      Only Time format   formatTime: 11:20:30      formatTimeFull: 11:20      formatTimeLong: 11:20:30 EET +0200      formatTimeLong: 11:20      ===============================================================      en_US   Date and Time format   format: 07-Sep-1980 11:20:30      formatFull: Sunday, 07 September 1980 11:20 o'clock EET +0200      formatLong: 07 September 1980 11:20:30 EET +0200      formatShort: 07/09/80 11:20      Only Date format   formatDate: 07-Sep-1980      formatDateFull: Sunday, 07 September 1980      formatDateLong: 07 September 1980      formatDateShort: 07/09/80      Only Time format   formatTime: 11:20:30      formatTimeFull: 11:20 o'clock EET +0200      formatTimeLong: 11:20:30 EET +0200      formatTimeLong: 11:20      ===============================================================

Defining Custom Formats
To define a custom format for dates and/or times you can use these methods:

  • int setFormat([string $format = I18N_DATETIME_DEFAULT]): Defines a custom format for dates and times specified by the $format argument.
  • int setDateFormat([string $format = I18N_DATETIME_DEFAULT]): Defines a custom format for dates specified by the $format argument.
  • int setTimeFormat([string $format = I18N_DATETIME_DEFAULT]): Defines a custom format for times specified by the $format argument.

The following code shows an example of defining a custom format for dates/times:

   setFormat();      print( $dateTime->format() ).'
'; //Get the current date and time in a custom format print 'A custom format for current date and time is: '; $myFormat = $dateTime->setFormat('d.m.Y , l H:i:s'); print $dateTime->format().'
'; //Get the custom date format only print 'A custom format only for the date is: '; $myDateFormat = $dateTime->setDateFormat( 'Today is l , d * m * y '); print( $dateTime->formatDate() ).'
'; //Get the custom time format only print 'A custom format only for the time is: '; $myTimeFormat = $dateTime->setTimeFormat( 'The fo ma ed cu e ime is : H Hou s i Mi u es a d s Seco ds'); print( $dateTime->formatTime() ).'
'; ?>

The output of this application is:

   The default current date and time is:       26-Jun-2008 10:40:11      A custom format for current date and time is:       26.06.2008 , Thursday 10:40:11      A custom format only for the date is:       Today is Thursday , 26 * 06 * 08       A custom format only for the time is:       The formatted current time is :       10 Hours 40 Minutes and 11 Seconds

You’ve seen some base concepts required for internationalization and how to achieve number, currency, date, and time formatting using the I18N package. Using these basic functions, you’re well on your way toward building internationalized web sites that display values appropriately for the user’s locale.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist