diff --git a/ext/intl/formatter/formatter.stub.php b/ext/intl/formatter/formatter.stub.php index e335698688d64..ebbdd4503e9b1 100644 --- a/ext/intl/formatter/formatter.stub.php +++ b/ext/intl/formatter/formatter.stub.php @@ -183,13 +183,13 @@ class NumberFormatter #[\Deprecated(since: '8.3')] public const int TYPE_CURRENCY = UNKNOWN; - public function __construct(string $locale, int $style, ?string $pattern = null) {} + public function __construct(string $locale, string|int $style, ?string $pattern = null) {} /** * @tentative-return-type * @alias numfmt_create */ - public static function create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter {} + public static function create(string $locale, string|int $style, ?string $pattern = null): ?NumberFormatter {} /** * @tentative-return-type @@ -208,7 +208,7 @@ public function parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE, * @tentative-return-type * @alias numfmt_format_currency */ - public function formatCurrency(float $amount, string $currency): string|false {} + public function formatCurrency(float $amount, ?string $currency = null): string|false {} /** * @param string $currency diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 0e3d8b797e721..e2623c2bf389e 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -1,15 +1,15 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: caaa6ff408bfd88ec9bb998ffd753f4de971ccff */ + * Stub hash: 017bc18ab85626a370410218d771d3e5c54556dd */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, style, IS_LONG, 0) + ZEND_ARG_TYPE_MASK(0, style, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_NumberFormatter_create, 0, 2, NumberFormatter, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, style, IS_LONG, 0) + ZEND_ARG_TYPE_MASK(0, style, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -24,9 +24,9 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_NumberFormatter_ ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, offset, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_NumberFormatter_formatCurrency, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_NumberFormatter_formatCurrency, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, amount, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, currency, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, currency, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_NumberFormatter_parseCurrency, 0, 2, MAY_BE_DOUBLE|MAY_BE_FALSE) diff --git a/ext/intl/formatter/formatter_class.c b/ext/intl/formatter/formatter_class.c index 7832824c94e1c..16e56c6bc0ef7 100644 --- a/ext/intl/formatter/formatter_class.c +++ b/ext/intl/formatter/formatter_class.c @@ -77,6 +77,9 @@ zend_object *NumberFormatter_object_clone(zend_object *object) } else { zend_throw_error(NULL, "Cannot clone uninitialized NumberFormatter"); } + if (FORMATTER_OBJECT2(nfo) != NULL) { + FORMATTER_OBJECT2(new_nfo) = FORMATTER_OBJECT2(nfo); + } return new_obj; } /* }}} */ diff --git a/ext/intl/formatter/formatter_class.h b/ext/intl/formatter/formatter_class.h index f7da2b2201917..65fec0dde8e49 100644 --- a/ext/intl/formatter/formatter_class.h +++ b/ext/intl/formatter/formatter_class.h @@ -39,6 +39,7 @@ extern zend_class_entry *NumberFormatter_ce_ptr; #define FORMATTER_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(NumberFormatter, nfo) #define FORMATTER_OBJECT(nfo) (nfo)->nf_data.unum +#define FORMATTER_OBJECT2(nfo) (nfo)->nf_data.unum2 #define FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(INTL_NUMBERFORMATTER, nfo) #define FORMATTER_METHOD_FETCH_OBJECT \ FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; \ @@ -47,6 +48,13 @@ extern zend_class_entry *NumberFormatter_ce_ptr; zend_throw_error(NULL, "Found unconstructed NumberFormatter"); \ RETURN_THROWS(); \ } +#define FORMATTER_METHOD_FETCH_OBJECT2 \ + FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; \ + if (FORMATTER_OBJECT(nfo) == NULL && FORMATTER_OBJECT2(nfo) == NULL) \ + { \ + zend_throw_error(NULL, "Found unconstructed NumberFormatter nor new NumberFormatter"); \ + RETURN_THROWS(); \ + } #endif // #ifndef FORMATTER_CLASS_H diff --git a/ext/intl/formatter/formatter_data.c b/ext/intl/formatter/formatter_data.c index 57dbc8bde6b5e..38befdcd1dcd7 100644 --- a/ext/intl/formatter/formatter_data.c +++ b/ext/intl/formatter/formatter_data.c @@ -42,6 +42,9 @@ void formatter_data_free( formatter_data* nf_data ) if( nf_data->unum ) unum_close( nf_data->unum ); + if ( nf_data->unum2 ) + unumf_close( nf_data->unum2 ); + nf_data->unum = NULL; intl_error_reset( &nf_data->error ); } diff --git a/ext/intl/formatter/formatter_data.h b/ext/intl/formatter/formatter_data.h index 817ad0d6055f3..b7636d85afbf6 100644 --- a/ext/intl/formatter/formatter_data.h +++ b/ext/intl/formatter/formatter_data.h @@ -18,6 +18,7 @@ #include #include +#include #include "intl_error.h" @@ -27,6 +28,9 @@ typedef struct { // formatter handling UNumberFormat* unum; + + // new formatter handling + UNumberFormatter* unum2; } formatter_data; formatter_data* formatter_data_create( void ); diff --git a/ext/intl/formatter/formatter_format.c b/ext/intl/formatter/formatter_format.c index 0323757ed8620..94381f140b3df 100644 --- a/ext/intl/formatter/formatter_format.c +++ b/ext/intl/formatter/formatter_format.c @@ -18,6 +18,7 @@ #include "php_intl.h" +#include #include #include "formatter_class.h" @@ -28,6 +29,7 @@ PHP_FUNCTION( numfmt_format ) { zval *number; + UFormattedNumber *result = NULL; zend_long type = FORMAT_TYPE_DEFAULT; UChar format_buf[32]; UChar* formatted = format_buf; @@ -42,7 +44,12 @@ PHP_FUNCTION( numfmt_format ) } /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; + FORMATTER_METHOD_FETCH_OBJECT2; + + if (FORMATTER_OBJECT2(nfo)) { + result = unumf_openResult(&INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error opening formatter result"); + } if(type == FORMAT_TYPE_DEFAULT) { switch(Z_TYPE_P(number)) { @@ -60,48 +67,77 @@ PHP_FUNCTION( numfmt_format ) switch(type) { case FORMAT_TYPE_INT32: convert_to_long(number); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), + formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + unumf_formatInt(FORMATTER_OBJECT2(nfo), (int32_t)Z_LVAL_P(number), result, &INTL_DATA_ERROR_CODE(nfo)); + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { intl_error_reset(INTL_DATA_ERROR_P(nfo)); formatted = eumalloc(formatted_len); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), + formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { efree(formatted); } } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); break; case FORMAT_TYPE_INT64: { int64_t value = (Z_TYPE_P(number) == IS_DOUBLE)?(int64_t)Z_DVAL_P(number):Z_LVAL_P(number); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + unumf_formatInt(FORMATTER_OBJECT2(nfo), value, result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { intl_error_reset(INTL_DATA_ERROR_P(nfo)); formatted = eumalloc(formatted_len); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { efree(formatted); } } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting to string failed" ); } break; case FORMAT_TYPE_DOUBLE: convert_to_double(number); - formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + unumf_formatDouble(FORMATTER_OBJECT2(nfo), Z_DVAL_P(number), result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { intl_error_reset(INTL_DATA_ERROR_P(nfo)); formatted = eumalloc(formatted_len); - unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo)) { + unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } else { + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { efree(formatted); } } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting to string failed" ); break; case FORMAT_TYPE_CURRENCY: if (getThis()) { @@ -119,6 +155,8 @@ PHP_FUNCTION( numfmt_format ) } INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); + + unumf_closeResult(result); } /* }}} */ @@ -133,33 +171,60 @@ PHP_FUNCTION( numfmt_format_currency ) size_t currency_len = 0; UChar* scurrency = NULL; int32_t scurrency_len = 0; + UFormattedNumber *result = NULL; FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ods", + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Od|s!", &object, NumberFormatter_ce_ptr, &number, ¤cy, ¤cy_len ) == FAILURE ) { RETURN_THROWS(); } /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert currency to UTF-16. */ - intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" ); - - /* Format the number using a fixed-length buffer. */ - formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - - /* If the buffer turned out to be too small - * then allocate another buffer dynamically - * and use it to format the number. - */ - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + FORMATTER_METHOD_FETCH_OBJECT2; + + if (FORMATTER_OBJECT(nfo)) { + if (!currency) { + zend_argument_value_error(3, "currency cannot be null when instantiating NumberFormatter" + "with a style constant"); + RETURN_THROWS(); + } + /* Convert currency to UTF-16. */ + intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" ); + + /* Format the number using a fixed-length buffer. */ + formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + + /* If the buffer turned out to be too small + * then allocate another buffer dynamically + * and use it to format the number. + */ + if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { + intl_error_reset(INTL_DATA_ERROR_P(nfo)); + formatted = eumalloc(formatted_len); + unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + } + } else { + /* The new NumberFormatter takes the currency format (aka skeleton) + * from NumberFormatter::__construct 2nd argument. + */ + zend_error(E_DEPRECATED, "Calling NumberFormat::formatCurrency when the object has been instantiated with the currency/* token is deprecated."); + result = unumf_openResult(&INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error opening formatter result"); + unumf_formatDouble(FORMATTER_OBJECT2(nfo), number, result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + /* If the buffer turned out to be too small + * then allocate another buffer dynamically + * and use it to format the number. + */ + if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { + intl_error_reset(INTL_DATA_ERROR_P(nfo)); + formatted = eumalloc(formatted_len); + formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo)); + } } if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) { @@ -176,6 +241,8 @@ PHP_FUNCTION( numfmt_format_currency ) if(scurrency) { efree(scurrency); } + + unumf_closeResult(result); } /* }}} */ diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c index 6f8fb98d21434..38b77561f523a 100644 --- a/ext/intl/formatter/formatter_main.c +++ b/ext/intl/formatter/formatter_main.c @@ -16,6 +16,8 @@ #include #endif +#include +#include #include #include @@ -30,13 +32,14 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ char* pattern = NULL; size_t locale_len = 0, pattern_len = 0; zend_long style; + zend_string *sstyle; UChar* spattern = NULL; int32_t spattern_len = 0; FORMATTER_METHOD_INIT_VARS; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STRING(locale, locale_len) - Z_PARAM_LONG(style) + Z_PARAM_STR_OR_LONG(sstyle, style) Z_PARAM_OPTIONAL Z_PARAM_STRING_OR_NULL(pattern, pattern_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); @@ -70,13 +73,24 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ } /* Create an ICU number formatter. */ - FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); + if (!sstyle) { + FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if(spattern) { - efree(spattern); + if(spattern) { + efree(spattern); + } + + INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); + } else { + UChar *bstyle = 0; + int32_t blen = 0; + intl_convert_utf8_to_utf16(&bstyle, &blen, ZSTR_VAL(sstyle), ZSTR_LEN(sstyle), &INTL_DATA_ERROR_CODE(nfo)); + INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting style to UTF-16"); + FORMATTER_OBJECT2(nfo) = unumf_openForSkeletonAndLocale(bstyle, blen, locale, &INTL_DATA_ERROR_CODE(nfo)); + efree(bstyle); + INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: new number formatter failed"); } - INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); return SUCCESS; } /* }}} */ diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index f3a80dd511943..79748148401eb 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -390,14 +390,14 @@ function datefmt_get_error_message(IntlDateFormatter $formatter): string {} /* formatter */ -function numfmt_create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter {} +function numfmt_create(string $locale, string|int $style, ?string $pattern = null): ?NumberFormatter {} function numfmt_format(NumberFormatter $formatter, int|float $num, int $type = NumberFormatter::TYPE_DEFAULT): string|false {} /** @param int $offset */ function numfmt_parse(NumberFormatter $formatter, string $string, int $type = NumberFormatter::TYPE_DOUBLE, &$offset = null): int|float|false {} -function numfmt_format_currency(NumberFormatter $formatter, float $amount, string $currency): string|false {} +function numfmt_format_currency(NumberFormatter $formatter, float $amount, ?string $currency = null): string|false {} /** * @param string $currency diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 11c585d8df63b..9e4811f023861 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 168eabfdcbf29189f2327448f104ea98752d1c5a */ + * Stub hash: 3ee1119dd8e96869880362d743146d6b0ebb3f76 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") @@ -369,7 +369,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_numfmt_create, 0, 2, NumberFormatter, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, style, IS_LONG, 0) + ZEND_ARG_TYPE_MASK(0, style, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -386,10 +386,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_numfmt_parse, 0, 2, MAY_BE_LONG| ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, offset, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_numfmt_format_currency, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_numfmt_format_currency, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, formatter, NumberFormatter, 0) ZEND_ARG_TYPE_INFO(0, amount, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, currency, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, currency, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_numfmt_parse_currency, 0, 3, MAY_BE_DOUBLE|MAY_BE_FALSE) diff --git a/ext/intl/tests/formatter_fail.phpt b/ext/intl/tests/formatter_fail.phpt index c9c621c6b7626..9ecbd4e887589 100644 --- a/ext/intl/tests/formatter_fail.phpt +++ b/ext/intl/tests/formatter_fail.phpt @@ -109,15 +109,15 @@ Error: NumberFormatter object is already constructed in %s on line %d Deprecated: NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d -Deprecated: NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d +Deprecated: NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type string|int is deprecated in %s on line %d Deprecated: NumberFormatter::create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d -Deprecated: NumberFormatter::create(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d +Deprecated: NumberFormatter::create(): Passing null to parameter #2 ($style) of type string|int is deprecated in %s on line %d Deprecated: numfmt_create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d -Deprecated: numfmt_create(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d +Deprecated: numfmt_create(): Passing null to parameter #2 ($style) of type string|int is deprecated in %s on line %d ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d 'U_ZERO_ERROR' diff --git a/ext/intl/tests/gh17006.phpt b/ext/intl/tests/gh17006.phpt new file mode 100644 index 0000000000000..56b7e5438979e --- /dev/null +++ b/ext/intl/tests/gh17006.phpt @@ -0,0 +1,34 @@ +--TEST-- +NumberFormatter::format using new API +--EXTENSIONS-- +intl +--FILE-- +format($number); +var_dump($oldv); +$newf = new \NumberFormatter('en_US', "compact-long"); +$newv = $newf->format($number); +var_dump($newv); + +$fmt = new \NumberFormatter('en_US', \NumberFormatter::CURRENCY_ACCOUNTING); +var_dump($fmt->formatCurrency($number, 'USD')); + +try { + $fmt->formatCurrency($number); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +$fmt = new \NumberFormatter('en_US', "group-auto currency/USD"); +var_dump($fmt->formatCurrency($number)); +?> +--EXPECTF-- +string(11) "one million" +string(9) "1 million" +string(13) "$1,000,000.00" +NumberFormatter::formatCurrency(): Argument #3 currency cannot be null when instantiating NumberFormatterwith a style constant + +Deprecated: Calling NumberFormat::formatCurrency when the object has been instantiated with the currency/* token is deprecated. in %s on line %d +string(13) "$1,000,000.00" diff --git a/ext/intl/tests/gh8115.phpt b/ext/intl/tests/gh8115.phpt index 47e32658e5a7d..e15c2ee84dc19 100644 --- a/ext/intl/tests/gh8115.phpt +++ b/ext/intl/tests/gh8115.phpt @@ -34,7 +34,7 @@ Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parame Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parameter #2 ($compiled) of type bool is deprecated Caught (8192): Collator::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated Caught (8192): NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated -Caught (8192): NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type int is deprecated +Caught (8192): NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type string|int is deprecated Caught (8192): MessageFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated Caught (8192): MessageFormatter::__construct(): Passing null to parameter #2 ($pattern) of type string is deprecated Caught (8192): ResourceBundle::__construct(): Passing null to parameter #3 ($fallback) of type bool is deprecated