• No results found

Formatting Strings

In document ZEND PHP 5 Certification (Page 103-108)

PHP provides a number of different functions that can be used to format output in a variety of ways. Some of them are designed to handle special data types—for exam- ple, numbers of currency values—while others provide a more generic interface for formatting strings according to more complex rules.

Formatting rules are sometimes governed bylocale considerations. For example, most English-speaking countries format numbers by using commas as the separa- tors between thousands, and the point as a separator between the integer portion of a number and its fractional part. In many European countries, this custom is re- versed: the dot (or a space) separates thousands, and the comma is the fractional delimiter.

In PHP, the current locale is set by calling thesetlocale()function, which takes two parameters: the name of the locale you want to set and a category that indicates which functions are affected by the change. For example, you can affect currency formatting (which we’ll examine in a few paragraphs) to reflect the standard US rules by callingsetlocale()as in the following example:

setlocale (LC_MONETARY, ’en_US’);

Formatting Numbers

Number formatting is typically used when you wish to output a number and separate its digits into thousands and decimal points. Thenumber_format()function, used for this purpose, isnot locale-aware. This means that, even if you have a French or German locale set , it will still use periods for decimals and commas for thousands, unless you specify otherwise.

Thenumber_format()function accepts 1, 2 or 4 arguments (but not three). If only one argument is given, the default formatting is used: the number will be rounded to the nearest integer, and a comma will be used to separate thousands. If two argu- ments are given, the number will be rounded to the given number of decimal places and a period and comma will be used to separate decimals and thousands, respec- tively. Should you pass in all four parameters, the number will be rounded to the

number of decimal places given, andnumber_format()will use the first character of the third and fourth arguments as decimal and thousand separators respectively.

Here are a few examples:

echo number_format("100000.698"); // Shows 100,001

echo number_format("100000.698", 3, ",", " "); // Shows 100 000,698

Formatting Currency Values

Currency formatting, unlike number formatting,is locale aware and will display the correct currency symbol (either international or national notations—e.g.:USDor$, respectively) depending on how your locale is set.

When usingmoney_format(), we must specify the formatting rules we want to use by passing the function a specially-crafted string that consists of a percent symbol (%) followed by a set of flags that determine the minimum width of the resulting out- put, its integer and decimal precision and a conversion character that determines whether the currency value is formatted using the locale’s national or international rules.

i

Themoney_format()function is not available on Windows, as well as on some variants of UNIX.

For example, to output a currency value using the American national notation with two decimal places, we’d use the following function call:

setlocale(LC_MONETARY, "en_US");

echo money_format(’%.2n’, "100000.698");

This example displays “$100,000.70”.

If we simply change the locale to Japanese, we can display the number in Yen.

setlocale(LC_MONETARY, "ja_JP.UTF-8");

86Strings And Patterns

This time, the output is “¥100,000.70”. Similarly, if we change our formatting to use theiconversion character,money_format()will produce its output using the interna- tional notation, for example:

setlocale(LC_MONETARY, "en_US");

echo money_format(’%.2i’, "100000.698");

setlocale(LC_MONETARY, "ja_JP");

echo money_format(’%.2i’, "100000.698");

The first example displays “USD 100,000.70”, while the second outputs “JPY 100,000.70”. As you can see, money_format()is a must for any international com- merce site that accepts multiple currencies, as it allows you to easily display amounts in currencies that you are not familiar with.

There are two important things that you should keep in mind here. First, a call tosetlocale()affects the entire process inside which it is executed, rather than the individual script. Thus, you should be careful to always reset the locale whenever you need to perform a formatting operation, particularly if your application requires the use of multiple locales, or is hosted alongside other applications that may.

In addition, you should keep in mind that the default rounding rules change from locale to locale. For example, US currency values are regularly expressed as dollars and cents, while Japanese currency values are represented as integers. Therefore, if you don’t specify a decimal precision, the same value can yield very different locale- dependent formatted strings:

setlocale(LC_MONETARY, "en_US");

echo money_format(’%i’, "100000.698");

setlocale(LC_MONETARY, "ja_JP");

echo money_format(’%i’, "100000.698");

The first example displays “USD 100,000.70”; however, the Japanese output is now “JPY 100,001”—as you can see, this last value was rounded up to the next integer.

Generic Formatting

If you are not handling numbers or currency values, you can use theprintf()fam- ily of functions to perform arbitrary formatting of a value. All the functions in this group perform in an essentially identical way: they take an input string that specifies the output format and one or more values. The only difference is in the way they re- turn their results: the “plain”printf()function simply writes it to the script’s output, while other variants may return it (sprintf()), write it out to a file (fprintf()), and so on.

The formatting string usually contains a combination of literal text—that is copied directly into the function’s output—and specifiers that determine how the input should be formatted. The specifiers are then used to format each input parameter in the order in which they are passed to the function (thus, the first specifier is used to format the first data parameter, the second specified is used to format the second parameter, and so on).

A formatting specifier always starts with a percent symbol (if you want to insert a literal percent character in your output, you need to escape it as%%) and is followed by a type specification token, which identifies the type of formatting to be applied; a number of optional modifiers can be inserted between the two to affect the output:

• Asign specifier (a plus of minus symbol) to determine how signed numbers are to be rendered

• Apadding specifier that indicates what character should be used to make up the required output length, should the input not be long enough on its own • An alignment specifier that indicates if the output should be left or right

aligned

• A numericwidth specifier that indicates the minimum length of the output • A precision specifier that indicates how many decimal digits should be dis-

played for floating-point numbers

It is important that you be familiar with some of the most commonly-used type spec- ifiers:

88Strings And Patterns

b Output an integer as a Binary number.

c Output the character which has the input integer as its ASCII value.

d Output a signed decimal number

e Output a number using scientific notation (e.g., 3.8e+9)

u Output an unsigned decimal number

f Output a locale aware float number

F Output a non-locale aware float number

o Output a number using its Octal representation

s Output a string

x Output a number as hexadecimal with lowercase letters

X Output a number as hexadecimal with uppercase letters Here are some simple examples ofprintf()usage:

$n = 123; $f = 123.45; $s = "A string";

printf ("%d", $n); // prints 123

printf ("%d", $f); // prints 1

// Prints "The string is A string"

printf ("The string is %s", $s);

// Example with precision

printf ("%3.3f", $f); // prints 123.450

// Complex formatting

function showError($msg, $line, $file) {

return sprintf("An error occured in %s on ". "line %d: %s", $file, $line, $msg); }

Parsing Formatted Input

Thesscanf()family of functions works in a similar way toprintf(), except that, in- stead of formatting output, it allows you to parse formatted input. For example, con- sider the following:

$data = ’123 456 789’; $format = ’%d %d %d’;

var_dump (sscanf ($data, $format));

When this code is executed, the function interprets its input according to the rules specified in the format string and returns an array that contains the parsed data:

array(3) { [0]=> int(123) [1]=> int(456) [2]=> int(789) }

Note that the data must match the format passed tosscanf()exactly—or the func- tion will fail to retrieve all the values. For this reason,sscanf()is normally only useful in those situations in which input follows a well-defined format (that is, it isnot pro- vided by the user!).

In document ZEND PHP 5 Certification (Page 103-108)