1

From the manual at: https://www.php.net/manual/en/numberformatter.format.php

public NumberFormatter::format ( int|float $value , int $type = ? ) : string

This code:

$a = new \NumberFormatter('en_US', \NumberFormatter::CURRENCY);
$string = $a->format(123, \NumberFormatter::TYPE_CURRENCY);
var_dump($string);

Causes this:

PHP Fatal error:  Uncaught ValueError: NumberFormatter::format(): Argument #3 must be a NumberFormatter::TYPE_* constant

Huh? Argument #3? There is no argument #3 (except in the procedural version)! And this code (thinking that maybe the documentation is wrong and nobody has ever spotted it before now):

$a = new \NumberFormatter('en_US', \NumberFormatter::CURRENCY);
$string = $a->format(123, 'USD', \NumberFormatter::TYPE_CURRENCY);
var_dump($string);

But it just causes this:

PHP Fatal error:  Uncaught ArgumentCountError: NumberFormatter::format() expects at most 2 arguments, 3 given

Okay... So how do you want it, PHP? Is it 3 or 2? I'm lost at this point.

Important: The reason I'm not using formatCurrency even though it is definitely a currency number, is that (in the real code) I'm trying to remove the currency symbol but otherwise format it as a currency. formatCurrency sadly ignores the setSymbol, but format honors it. That's why format is used in this case. Thus, please don't tell me to use formatCurrency.

user15080516
  • 121
  • 5

1 Answers1

1

It appears that the documentation on the intl extension is a little incomplete or misleading. It would seem that calling format() without the second type argument will produce the output you want on your NumberFormatter::CURRENCY object:

$a = new \NumberFormatter('en_US', \NumberFormatter::CURRENCY);
echo $string = $a->format('123');
// $123.00

$a = new \NumberFormatter('en_GB', \NumberFormatter::CURRENCY);
echo $string = $a->format('123');
// £123.00

The docs show that argument as optional but do not apparently explain how or when it should be used. In this case, omitting it seems to do the job.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
  • Hmm! Makes sense in a way. Since the "currency type" is already set in a way. Seems to work. ("Seems" being the keyword... so far!) – user15080516 Jan 29 '21 at 21:19
  • Yeah. It bugs me that I don't understand it, I have been playing with it and have not found a way to make that parameter work. Maybe it is only relevant in a procedural context if the NumberFormatter object hasn't been created? I don't know. You can't call `new NumberFormatter()` without a type to begin with, so it's not like you can instantiate a generic one and set types at format call time /shrug. – Michael Berkowski Jan 29 '21 at 21:24