NumberFormatter货币符号(前置)

时间:2013-09-17 10:23:17

标签: php intl numberformatter


我正在使用Intl库来格式化带有货币符号的数字。

$number = new NumberFormatter('es_ES', NumberFormatter::CURRENCY);
echo $number->format('234234.234324');

我的本地php版本:

version 1.1.0
ICU version 50.1.2
ICU Data version    50.1

服务器

version 1.1.0
ICU version 50.1.2

结果:
我的版本:234.234,23€
服务器版本:€234.234,23

货币符号应位于数字的末尾,而不是位于数字的开头

由于

2 个答案:

答案 0 :(得分:0)

我把它作为帮手。

/**
 * Number format wrapper
 */
class NumberFormat extends Helper\NumberFormat {
    private $serviceLocator;

    public function setServiceLocator($service) {
        $this->serviceLocator = $service;
    }
    /**
     * Number format
     * @param type $number
     * @param type $decimals
     * @param type $formatStyle
     * @param string $currency
     * @param type $locale
     * @return string
     */
    public function __invoke(
        $number,
        $decimals    = null,
        $formatStyle = null,
        $currency  = null,
        $locale      = null
    ) {

        $currency = strtoupper($currency);
        //get current locale
        $currentLocale = $this->serviceLocator->get('translator')->getLocale();
        $config  =  $this->serviceLocator->get('config');

        //mapping between countries
        if(isset($config['application-options']['currency-symbol-map'][$currentLocale])) {
            $currenciesMapping = $config['application-options']['currency-symbol-map'];
            $localeCurrency = $currenciesMapping[$currentLocale];
            //England pound != euro
            if(strtolower($currency) != $localeCurrency) {
                $locale = array_search($currency,$currenciesMapping);
            }
        };

        if (!$locale) {
            $locale = $currentLocale;
        }
        if (null === $formatStyle) {
            $formatStyle = $this->getFormatStyle();
        }

        if (!is_int($decimals) || $decimals < 0) {
            $decimals = $this->getDecimals();
        }
        // 6.000000 should be 6.00 and decimals more than 2
        $numberExplode = explode('.',$number);

        if($decimals > 2 && $numberExplode[1] == 0) {
            $decimals = 2;
        }

        $formatType = $this->getFormatType();

        $formatterId = md5($formatStyle . "\0" . $locale . "\0" . $decimals);

        if (!isset($this->formatters[$formatterId])) {
            $this->formatters[$formatterId] = new NumberFormatter(
                $locale,
                $formatStyle
            );

            if ($decimals !== null) {
                $this->formatters[$formatterId]->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
                $this->formatters[$formatterId]->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
            }
        }

        //modify pattern
        //always at the begining
        if($formatStyle == \NumberFormatter::CURRENCY) {
            $pattern = str_replace('¤','',$this->formatters[$formatterId]->getPattern());
            $this->formatters[$formatterId]->setPattern('¤'.$pattern);
        }
        if($currency == null)
            return  $this->formatters[$formatterId]->format($number, $formatType);
        else
            return $this->formatters[$formatterId]->formatCurrency($number,$currency);
    }
}

答案 1 :(得分:0)

Plesk用PHP 7.1安装的intl扩展名存在完全相同的问题。

$ /opt/plesk/php/7.1/bin/php -a
Interactive shell

php > $a = new \NumberFormatter("es_ES", \NumberFormatter::CURRENCY);
php > echo $a->format(12345.12345);
€ 12.345,12

/opt/plesk/php/7.1/bin/php -i一起使用的是那些正在使用的ICU版本:

version  => 1.1.0
ICU version  => 4.2.1

要解决此问题,我必须从源代码中编译较新版本的ICU(我能够无错误编译的最新版本是58.2),然后还使用源代码从源代码中为我的PHP版本编译了intl扩展名。 ICU(因为我使用的是Plesk,PHP的二进制文件就是它使用的二进制文件):

wget http://download.icu-project.org/files/icu4c/58.2/icu4c-58_2-src.tgz
tar xzvf icu4c-58_2-src.tgz
cd icu/source/
CXXFLAGS="-std=c++0x" ./runConfigureICU Linux --prefix=/opt/icu4c-58_2
make
sudo make install

cd ../../

wget http://php.net/distributions/php-7.1.22.tar.gz
tar xzvf php-7.1.22.tar.gz
cd php-7.1.22/ext/intl
/opt/plesk/php/7.1/bin/phpize
./configure --with-php-config=/opt/plesk/php/7.1/bin/php-config --enable-intl --with-icu-dir=/opt/icu4c-58_2
make
sudo make install

然后确保已加载扩展名,在我的情况下为/opt/plesk/php/7.1/etc/php.d/intl.ini

; Enable intl extension module
extension=intl.so

然后重新启动或重新加载httpd,Apache,PHP-FPM或正在加载PHP的内容:

sudo service httpd restart

/opt/plesk/php/7.1/bin/php -i现在显示的版本:

version => 1.1.0
ICU version => 58.2
ICU Data version => 58.2

现在正确显示了货币:

$ /opt/plesk/php/7.1/bin/php -a
Interactive shell

php > $a = new \NumberFormatter("es_ES", \NumberFormatter::CURRENCY);
php > echo $a->format(12345.12345);
12.345,12 €