2


我正在使用 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 €<br> 服务器版本:€ 234.234,23

货币符号应该在数字的末尾而不是数字的开头

谢谢

4

2 回答 2

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);
    }
}
于 2015-01-29T14:16:05.563 回答
0

intl我在Plesk 使用 PHP 7.1 安装的扩展上遇到了完全相同的问题。

$ /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

这些是它使用的 ICU 版本,如下所示/opt/plesk/php/7.1/bin/php -i

version  => 1.1.0
ICU version  => 4.2.1

为了解决这个问题,我必须从源代码编译一个较新版本的 ICU(我能够正确编译的最新版本是 58.2),然后还intl使用该 ICU 从源代码编译我的 PHP 版本的扩展(因为我正在使用 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 €
于 2018-10-28T18:00:25.863 回答