【问题标题】:NumberFormatter currency symbol(prepend)NumberFormatter 货币符号(前置)
【发布时间】:2013-09-21 17:45:26
【问题描述】:


我正在使用 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

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

谢谢

【问题讨论】:

    标签: php intl numberformatter


    【解决方案1】:

    我是作为帮手做的。

    /**
     * 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      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
      

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

      version  => 1.1.0
      ICU version  => 4.2.1
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-23
        • 1970-01-01
        • 2013-10-18
        • 2018-03-08
        相关资源
        最近更新 更多