thousands separator).
getallheaders(), apache_request_headers() and apache_response_headers()
. Improved performance of FastCGI request parsing.
+- Improved core functions:
+ . number_format() no longer truncates multibyte decimal points and thousand
+ separators to the first byte. FR #53457. (Adam)
+
- Improved CURL extension:
. Added support for CURLOPT_MAX_RECV_SPEED_LARGE and
CURLOPT_MAX_SEND_SPEED_LARGE. FR #51815. (Pierrick)
behavior follows the recommendations of Unicode Technical Report #36.
- htmlspecialchars_decode/html_entity_decode now decode ' if the document
type is ENT_XML1, ENT_XHTML, or ENT_HTML5.
+- number_format() no longer truncates multibyte decimal points and thousand
+ separators to the first byte.
- The third parameter ($matches) to preg_match_all() is now optional. If
omitted, the function will simply return the number of times the pattern was
matched in the subject and will have no other side effects.
/* {{{ _php_math_number_format
*/
PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep)
+{
+ return _php_math_number_format_ex(d, dec, &dec_point, 1, &thousand_sep, 1);
+}
+
+PHPAPI char *_php_math_number_format_ex(double d, int dec, char *dec_point, size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len)
{
char *tmpbuf = NULL, *resbuf;
char *s, *t; /* source, target */
/* allow for thousand separators */
if (thousand_sep) {
- integral += (integral-1) / 3;
+ integral += thousand_sep_len * ((integral-1) / 3);
}
reslen = integral;
reslen += dec;
if (dec_point) {
- reslen++;
+ reslen += dec_point_len;
}
}
/* add decimal point */
if (dec_point) {
- *t-- = dec_point;
+ t -= dec_point_len;
+ memcpy(t + 1, dec_point, dec_point_len);
}
}
while(s >= tmpbuf) {
*t-- = *s--;
if (thousand_sep && (++count%3)==0 && s>=tmpbuf) {
- *t-- = thousand_sep;
+ t -= thousand_sep_len;
+ memcpy(t + 1, thousand_sep, thousand_sep_len);
}
}
RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0);
break;
case 4:
- if (dec_point != NULL) {
- if (dec_point_len) {
- dec_point_chr = dec_point[0];
- } else {
- dec_point_chr = 0;
- }
+ if (dec_point == NULL) {
+ dec_point = &dec_point_chr;
+ dec_point_len = 1;
}
- if (thousand_sep != NULL) {
- if (thousand_sep_len) {
- thousand_sep_chr = thousand_sep[0];
- } else {
- thousand_sep_chr = 0;
- }
+
+ if (thousand_sep == NULL) {
+ thousand_sep = &thousand_sep_chr;
+ thousand_sep_len = 1;
}
- RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0);
+
+ RETURN_STRING(_php_math_number_format_ex(num, dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len), 0);
break;
default:
WRONG_PARAM_COUNT;
#ifndef PHP_MATH_H
#define PHP_MATH_H
-PHPAPI char *_php_math_number_format(double, int, char , char);
+PHPAPI char *_php_math_number_format(double, int, char, char);
+PHPAPI char *_php_math_number_format_ex(double, int, char *, size_t, char *, size_t);
PHPAPI char * _php_math_longtobase(zval *arg, int base);
PHPAPI long _php_math_basetolong(zval *arg, int base);
PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret);
--- /dev/null
+--TEST--
+Test number_format() - multiple character separator support
+--FILE--
+<?php
+$values = array(1234.5678,
+ -1234.5678,
+ 1234.6578e4,
+ -1234.56789e4,
+ 0x1234CDEF,
+ 02777777777,
+ "123456789",
+ "123.456789",
+ "12.3456789e1",
+ null,
+ true,
+ false);
+
+echo " number_format tests.....multiple character decimal point\n";
+for ($i = 0; $i < count($values); $i++) {
+ $res = number_format($values[$i], 2, '·', ' ');
+ var_dump($res);
+}
+
+echo "\n number_format tests.....multiple character thousand separator\n";
+for ($i = 0; $i < count($values); $i++) {
+ $res = number_format($values[$i], 2, '.' , ' ');
+ var_dump($res);
+}
+
+echo "\n number_format tests.....multiple character decimal and thousep\n";
+for ($i = 0; $i < count($values); $i++) {
+ $res = number_format($values[$i], 2, '·' , ' ');
+ var_dump($res);
+}
+?>
+--EXPECTF--
+ number_format tests.....multiple character decimal point
+string(13) "1 234·57"
+string(14) "-1 234·57"
+string(18) "12 346 578·00"
+string(19) "-12 345 678·90"
+string(19) "305 450 479·00"
+string(19) "402 653 183·00"
+string(19) "123 456 789·00"
+string(11) "123·46"
+string(11) "123·46"
+string(9) "0·00"
+string(9) "1·00"
+string(9) "0·00"
+
+ number_format tests.....multiple character thousand separator
+string(15) "1 234.57"
+string(16) "-1 234.57"
+string(27) "12 346 578.00"
+string(28) "-12 345 678.90"
+string(28) "305 450 479.00"
+string(28) "402 653 183.00"
+string(28) "123 456 789.00"
+string(6) "123.46"
+string(6) "123.46"
+string(4) "0.00"
+string(4) "1.00"
+string(4) "0.00"
+
+ number_format tests.....multiple character decimal and thousep
+string(20) "1 234·57"
+string(21) "-1 234·57"
+string(32) "12 346 578·00"
+string(33) "-12 345 678·90"
+string(33) "305 450 479·00"
+string(33) "402 653 183·00"
+string(33) "123 456 789·00"
+string(11) "123·46"
+string(11) "123·46"
+string(9) "0·00"
+string(9) "1·00"
+string(9) "0·00"