我正在使用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
货币符号应位于数字的末尾,而不是位于数字的开头
由于
答案 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 €