 
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.