Use the pc_format_currency( ) function, shown in Example 16-1, to produce an appropriately formatted string. For example:
setlocale(LC_ALL,'fr_CA'); print pc_format_currency(-12345678.45); (12 345 678,45 $)
The pc_format_currency( ) function, shown in Example 16-1, gets the currency formatting information from localeconv( ) and then uses number_format( ) and some logic to construct the correct string.
function pc_format_currency($amt) { // get locale-specific currency formatting information $a = localeconv(); // compute sign of $amt and then remove it if ($amt < 0) { $sign = -1; } else { $sign = 1; } $amt = abs($amt); // format $amt with appropriate grouping, decimal point, and fractional digits $amt = number_format($amt,$a['frac_digits'],$a['mon_decimal_point'], $a['mon_thousands_sep']); // figure out where to put the currency symbol and positive or negative signs $currency_symbol = $a['currency_symbol']; // is $amt >= 0 ? if (1 == $sign) { $sign_symbol = 'positive_sign'; $cs_precedes = 'p_cs_precedes'; $sign_posn = 'p_sign_posn'; $sep_by_space = 'p_sep_by_space'; } else { $sign_symbol = 'negative_sign'; $cs_precedes = 'n_cs_precedes'; $sign_posn = 'n_sign_posn'; $sep_by_space = 'n_sep_by_space'; } if ($a[$cs_precedes]) { if (3 == $a[$sign_posn]) { $currency_symbol = $a[$sign_symbol].$currency_symbol; } elseif (4 == $a[$sign_posn]) { $currency_symbol .= $a[$sign_symbol]; } // currency symbol in front if ($a[$sep_by_space]) { $amt = $currency_symbol.' '.$amt; } else { $amt = $currency_symbol.$amt; } } else { // currency symbol after amount if ($a[$sep_by_space]) { $amt .= ' '.$currency_symbol; } else { $amt .= $currency_symbol; } } if (0 == $a[$sign_posn]) { $amt = "($amt)"; } elseif (1 == $a[$sign_posn]) { $amt = $a[$sign_symbol].$amt; } elseif (2 == $a[$sign_posn]) { $amt .= $a[$sign_symbol]; } return $amt;
The code in pc_format_currency( ) that puts the currency symbol and sign in the correct place is almost identical for positive and negative amounts; it just uses different elements of the array returned by localeconv( ). The relevant elements of localeconv( )'s returned array are shown in Table 16-1.
Array element |
Description |
---|---|
currency_symbol |
Local currency symbol |
mon_decimal_point |
Monetary decimal point character |
mon_thousands_sep |
Monetary thousands separator |
positive_sign |
Sign for positive values |
negative_sign |
Sign for negative values |
frac_digits |
Number of fractional digits |
p_cs_precedes |
1 if currency_symbol should precede a positive value, 0 if it should follow |
p_sep_by_space |
1 if a space should separate the currency symbol from a positive value, 0 if not |
n_cs_precedes |
1 if currency_symbol should precede a negative value, 0 if it should follow |
n_sep_by_space |
1 if a space should separate currency_symbol from a negative value, 0 if not |
p_sign_posn |
Positive sign position:
|
n_sign_posn |
Negative sign position: same possible values as p_sign_posn |
There is a function in the C library called strfmon( ) that does for currency what strftime( ) does for dates and times; however, it isn't implemented in PHP. The pc_format_currency( ) function provides most of the same capabilities.
Section 2.10 also discusses number_format( ); documentation on localeconv( ) at http://www.php.net/localeconv and number_format( ) at http://www.php.net/number-format.
Copyright © 2003 O'Reilly & Associates. All rights reserved.