我正在使用Intl libary来用货币符号格式化数字。
$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欧元
货币符号应该在数字的末尾,而不是数字的开头。
谢谢
发布于 2015-01-29 14:16:05
我是做帮手的。
/**
* 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);
}
}发布于 2018-10-28 18:00:25
Plesk在PHP7.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),然后也从源代码中编译我的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或其他正在加载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 €https://stackoverflow.com/questions/18847278
复制相似问题