CHAPTER 9 – Locales
The mbstring extension has similar functions: mb_substr()and mb_strpos(). In addition, it has functions that can be used instead of the standard PHP functions strtoupper() and strtolower() (respectively, mb_strtoupper() and mb_strtolower()). The mbstring functions take into account Unicode proper- ties so that they correctly change the string to upper- or lowercase characters for any supported character. But you don't have to use the mbstring functions to do this for you because your operating system's standard function library should support this by default. Information on how to upper- or lowercase a character is stored in a language's locale. A locale is a collection of informa- tion defining the properties of language-dependent settings, such as the date/ time formats, number formats, and also which uppercase character correspon- dents to a lowercase character and vice versa. In PHP, you can use the setlo- cale() function to set a new locale or query the current locale. There are a few different "types" of locales; each type is meant to control a different type of lan- guage-dependent property. The different types are shown in Table 9.9. Table 9.9 Locale Types Type Description Example(s) LC_COLLATE Determines This setting has no effect on the standard PHP function to com- the meaning pare strings: strcmp(). Instead of using this function, you need of the w and to use the strcoll() function to compare strings according to other classes the locale: for regular expressions, <?php and shows /* Setting the standard "C" locale */ how compar- setlocale(LC_COLLATE, 'C'); ing strings echo strcoll('åtte', 'ære'), "n"; works.
/* Setting the "Norwegian" locale */ setlocale(LC_COLLATE, 'no_NO'); echo strcoll('åtte', 'ære'), "n"; ?> In Norwegian, the letter "æ" comes before the "å", but in the stan- dard "C" locale, the "å" comes after the "" because its ordinal value is higher (230 versus 229). The output is therefore -1 2
Table 9.9 Locale Types Type Description Example(s) LC_CTYPE Determines <?php how strings /* Setting the standard "C" locale */ are com- setlocale(LC_CTYPE, 'C'); pared, char- echo strtoupper('åtte'), "n"; acter
conversion is performed /* Setting the "Norwegian" locale */ and upper- setlocale(LC_CTYPE, 'no_NO'); and lowercas- echo strtoupper('åtte'), "n"; ing is han- ?> dled. In the standard "C" locale, there is no "å" defined, so there is no uppercase value of it. In Norwegian, the uppercase value is "Å," so the output of this script is åTTE ÅTTE LC_TIME Determines This locale type affects the strftime() function. We already formatting of showed you the different modifiers for the strftime() function date and time when dealing with the date and time handling functions, so here is values. a short example to show how the locale affects the output of the strftime() function (the %c modifier returns the preferred date/ time format defined by the locale): <?php setlocale(LC_TIME, 'en_US'); echo strftime('%c'), "n"; setlocale(LC_TIME, 'nl_NL'); echo strftime('%c'), "n"; setlocale(LC_TIME, 'no_NO'); echo strftime('%c'), "n"; ?> This outputs Fri 09 Apr 2004 11:13:52 AM CEST vr 09 apr 2004 11:13:52 CEST fre 09-04-2004 11:13:52 CEST LC_MESSAGES Determines Because setlocale() only has effect on the current program, the language we need to use the putenv() function in this example to set the in which LC_MESSAGES locale to a different one: application's messages <?php appear. This /* Setting the standard "C" locale */ has no influ- putenv('LC_MESSAGES=C'); ence on echo exec('cat nothere'); PHP's mes-
sages or errors, only /* Setting the "Norwegian" locale */ on applica- putenv('LC_MESSAGES=no_NO'); tions that you echo exec('cat nothere'); might start ?> from PHP. This outputs cat: nothere: No such file or directory cat: nothere: Ingen slik fil eller filkatalog
Table 9.9 Locale Types Type Description Example(s) LC_MONETARY Determines In PHP, these locale types affect the localeconv() function that the format returns information on how numbers and currency should be for- of monetary matted according to a locale's properties: information, such as <?php prices. function return_money($amount) { $li = localeconv();
$number = number_format($amount, $li['frac_digits'], $li['mon_decimal_point'], $li['mon_thousands_sep']);
if ($amount > 0) { $sign_placement = $li['p_sign_posn']; $cs_placement = $li['p_cs_precedes']; $space = $li['p_sep_by_space'] ? ' ' : ''; $sign = $li['positive_sign']; } else { $sign_placement = $li['n_sign_posn']; $cs_placement = $li['n_cs_precedes']; $space = $li['n_sep_by_space'] ? ' ' : ''; $sign = $li['negative_sign']; }
switch ($li['p_sign_posn']) { case 0: $format = ($sign_placement) ? '(%3$s%4$s%1$s)' : '(%1$s%4$s%3$s)'; break; case 1: $format = ($sign_placement) ? '%2$s %3$s%4$s%1$s' : '%2$s %1$s%4$s%3$s'; break; case 2: $format = ($sign_placement) ? '%3$s%4$s%1$s %2$s' : '%1$s%4$s%3$s %2$s'; break; case 3: $format = ($sign_placement) ? '%2$s %3$s%4$s%1$s' : '%1$s%4$s%2$s %3$s'; break; case 4: $format = ($sign_placement) ? '%3$s %2$s%4$s%1$s' : '%1$s%4$s%3$s %2$s'; break; } return sprintf($format. "n", abs($amount), $li['currency_symbol'], $sign, $space); }
setlocale(LC_ALL, 'nl_NL'); echo return_money(-1291.81); echo return_money(1291.81); ?> As you can see, we need a lot of code if we want to format numer- ical information correctly according to the locale; unfortunately, PHP does not have a built-in function for this.
Table 9.9 Locale Types Type Description Example(s) LC_NUMERIC Determines the format of numbers, such as the decimal point and thousands separator.
SUMMARY This chapter discusses miscellaneous features of PHP that are often needed for advanced PHP programming. This chapter provides information about working with streams--a feature of PHP--and about other features, such as regular expressions, date and time functions, building images, and converting between character sets--all features provided by PHP extensions. Beginning with PHP 4.3.0, you can interact with files, processes, pro- grams, or networks using streams. You can open, read, write, copy, rename, and otherwise manipulate local and remote files, including compressed files, and you can pipe information into and out of processes and programs using PHP functions that work with streams. Many stream functions are available, such as fopen(), which opens a file or URL for reading and/or writing data, and proc_open(), which starts a process by executing a command and establishes a pipe to the process that you can use to send and receive information from the process. Regular expressions enable you to create patterns that you can then com- pare to text. Regular expressions are powerful mechanisms for testing text for flow control and for validating user input. Perl regular expressions, provided by the PCRE extension that is enabled by default, consist of a string of special characters and text representing general patterns that match text, such as [0- 9] that matches any character between 0 and 9. PHP provides several exten- sions for using regular expressions, such as preg_match() that matches a string to a pattern and returns the matching strings in an array, and preg_replace that replaces a string that matches a pattern with another specified string. Other important functions provided by PHP allow special handling of dates and times, the creation of images, and the conversion of text from one character set to another. Date and time functions enable you to store any date, including now, and format the date in many ways, taking locale and Daylight Savings Time (DST) into account. The GD extension (not enabled by default) has many functions that enable you to build images, including color images containing text and bar charts. The iconv and mbstring extensions provide function that allow you to convert from one character set to another, such as converting a text string from ISO-8859-15 (Latin 9) to UTF-8. Locales are def- initions on how different languages and/or area represent text, date and time, and money. You can use the PHP function setlocale() to switch between locales and select different locales for different locale types.