价格的精度处理在程序中至关重要,在WooCommerce中就有一连串的函数对价格进行精度操作。我提取出来是这样的,可以在任何程序中使用:
<?php
// 消毒
function sanitize_text( $str, $keep_newlines = false ) {
if ( is_object( $str ) || is_array( $str ) ) {
return '';
}
$filtered = (string) $str;
if ( stripos($filtered, '<') !== false) {
$filtered = str_replace( '<', '<', $filtered );
$filtered = preg_replace( '@<(script|style)[^>]*?>.*?</\1>@si', '', $filtered );
$filtered = strip_tags( $filtered );
$filtered = str_replace( "<\n", "<\n", $filtered );
}
if ( ! $keep_newlines ) {
$filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
}
$filtered = trim( $filtered );
// Remove percent-encoded characters.
$found = false;
while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
$filtered = str_replace( $match[0], '', $filtered );
$found = true;
}
if ( $found ) {
// Strip out the whitespace that may now exist after removing percent-encoded characters.
$filtered = trim( preg_replace( '/ +/', ' ', $filtered ) );
}
return $filtered;
}
function get_price_decimals(){//小数点位数
return 0;
}
function get_price_decimal_separator(){//小数点分割符
return '.';
}
function get_rounding_precision() {// 精度+2,最小值为6
$precision = get_price_decimals() + 2;
if ( $precision < absint( 6 ) ) {
$precision = absint( 6 );
}
return $precision;
}
function price_format_decimal( $number, $dp = false, $trim_zeros = false ) {// 价格格式化
$number = $number ?? '';
$locale = localeconv();
$decimals = array( get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] );
// Remove locale from string.
if ( ! is_float( $number ) ) {
$number = str_replace( $decimals, '.', $number );
// Convert multiple dots to just one.
$number = preg_replace( '/\.(?![^.]+$)|[^0-9.-]/', '', sanitize_text($number) );
}
if ( false !== $dp ) {
$dp = intval( '' === $dp ? get_price_decimals() : $dp );
$number = number_format( floatval( $number ), $dp, '.', '' );
} elseif ( is_float( $number ) ) {
// DP is false - don't use number format, just return a string using whatever is given. Remove scientific notation using sprintf.
$number = str_replace( $decimals, '.', sprintf( '%.' . get_rounding_precision() . 'f', $number ) );
// We already had a float, so trailing zeros are not needed.
$trim_zeros = true;
}
if ( $trim_zeros && strstr( $number, '.' ) ) {
$number = rtrim( rtrim( $number, '0' ), '.' );
}
return $number;
}
使用也很简单:
$number = 3.59;
$decimal_places = get_price_decimals();
$formatted_number = price_format_decimal( $number, $decimal_places );
$number = 2.948;
$decimal_places = 2;
$formatted_number = price_format_decimal( $number, $decimal_places );
而根据我查阅资料,最终得出两种处理精度的方式:
$number = 3.59;
$decimal_places = 2;
$number_format = number_format( floatval( $number ), $decimal_places, '.', '' );
$round = round($number*pow(10, $decimal_places))/pow(10, $decimal_places);
最终WooCommerce中的计算函数、与另外两个计算结果一模一样。需要注意的是number_format出的精度只是显示是处理了,但是不会改变其值,与原值比较是一样的,而经过round处理的值会是一个新值,有时候可以搭配起来使用,比如数据库中存在的是6位小数,而只给用户看两位,就可以配合起来使用了。
© 版权声明
THE END
暂无评论内容