From 7b1f5637b6f4024ab081b1eb97681102b3eeae70 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 4 Aug 2026 22:01:44 -0400 Subject: [PATCH 01/25] Fix segfault comparing uninitialized SimpleXMLElement instances sxe_objects_compare dereferenced document->ptr when both nodes were NULL without checking document. A subclass that skips parent __construct leaves document NULL, so $a == $b segfaulted. Compare the documents only when both are set; anything else is uncomparable. Closes GH-23067 --- NEWS | 2 ++ ext/simplexml/simplexml.c | 2 +- .../tests/bug_sxe_compare_uninitialized.phpt | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt diff --git a/NEWS b/NEWS index e3995c5664bd..d19e6b8ae2af 100644 --- a/NEWS +++ b/NEWS @@ -62,6 +62,8 @@ PHP NEWS - SimpleXML: . Fixed integer element offsets that cannot resolve aliasing an existing element. (iliaal) + . Fixed segfault when comparing uninitialized SimpleXMLElement + instances. (iliaal) - Sockets: . Fixed various memory related issues in ext/sockets. (David Carlier) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index f3c1a073fcaf..1a346200199b 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1237,7 +1237,7 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */ if (sxe1->node == NULL && sxe2->node == NULL) { /* Both nodes not set: Only support equality comparison between documents. */ - if (sxe1->document->ptr == sxe2->document->ptr) { + if (sxe1->document != NULL && sxe2->document != NULL && sxe1->document->ptr == sxe2->document->ptr) { return 0; } return ZEND_UNCOMPARABLE; diff --git a/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt new file mode 100644 index 000000000000..4d915b66c3a3 --- /dev/null +++ b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt @@ -0,0 +1,28 @@ +--TEST-- +Comparing uninitialized SimpleXMLElement instances must not segfault +--EXTENSIONS-- +simplexml +--FILE-- +'); +echo "uninit vs init: "; +var_dump($a == $c); +echo "done\n"; +?> +--EXPECT-- +self: bool(true) +equal: bool(false) +identical: bool(false) +uninit vs init: bool(false) +done From 2f08d44e867b567fafe79b4da3a692d64263f003 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 10 Aug 2026 16:28:33 +0100 Subject: [PATCH 02/25] ext/intl: IntlNumberRangeFormatter::format() crash when the formatting fails. When formatFormattableRange() failed, the error was set (which throws, as exceptions are force-enabled there) but execution fell through to intl_charFromString(), which returns NULL for the bogus result, and the NULL zend_string ended up in return_value as an IS_STRING zval. The engine then dereferenced it while discarding the return value. The conversion is now only attempted for a successful formatting and both failure paths return early. createFromSkeleton() had the same shape of defect without the crash: the skeleton failure path threw and then still built a LocalizedNumberRangeFormatter out of the failed skeleton, so it bails out early as well. Additionally, format() reset the global error slot and the object one separately, and both methods reset before parsing their parameters, so a TypeError also cleared the state. Use intl_errors_reset(), which covers both slots, and reset once the parameters are known to be good. Close GH-23198 --- NEWS | 2 + .../rangeformatter/rangeformatter_class.cpp | 31 ++++++--- .../rangeformatter_error_reset_scope.phpt | 64 +++++++++++++++++++ .../rangeformatter_format_failure.phpt | 54 ++++++++++++++++ 4 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_error_reset_scope.phpt create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_format_failure.phpt diff --git a/NEWS b/NEWS index 1fa28e590846..2d6cde54b325 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,8 @@ PHP NEWS . Added SpoofChecker::areBidiConfusable(). (David Carlier) . Added SpoofChecker::getBidiSkeleton(). (Weilin Du) . Added SpoofChecker::getSkeleton(). (David Carlier) + . Fixed IntlNumberRangeFormatter::format() crash when the formatting fails. + (David Carlier) - PDO: . Fixed pdo_raise_impl_error() emitting a warning under ERRMODE_SILENT. diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 95acfccd2452..37b49e4f1310 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -88,8 +88,6 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) zend_long collapse; zend_long identityFallback; - intl_error_reset(NULL); - ZEND_PARSE_PARAMETERS_START(4,4) Z_PARAM_STRING(skeleton, skeleton_len) Z_PARAM_STRING(locale, locale_len) @@ -97,6 +95,8 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) Z_PARAM_LONG(identityFallback) ZEND_PARSE_PARAMETERS_END(); + intl_error_reset(NULL); + if (locale_len == 0) { locale = (char *)intl_locale_get_default(); } @@ -138,6 +138,8 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) INTL_G(use_exceptions) = old_use_exception; INTL_G(error_level) = old_error_level; + + RETURN_THROWS(); } LocalizedNumberRangeFormatter* nrf = new LocalizedNumberRangeFormatter( @@ -160,16 +162,17 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) zval *start; zval *end; - intl_error_reset(NULL); - IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); - intl_error_reset(RANGEFORMATTER_ERROR_P(obj)); ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_NUMBER(start) Z_PARAM_NUMBER(end) ZEND_PARSE_PARAMETERS_END(); + intl_errors_reset(RANGEFORMATTER_ERROR_P(obj)); + + ZEND_ASSERT(RANGEFORMATTER_OBJECT(obj) != NULL); + UErrorCode error = U_ZERO_ERROR; icu::Formattable start_formattable = rangeformatter_create_formattable(start); @@ -183,19 +186,29 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) INTL_G(use_exceptions) = true; INTL_G(error_level) = 0; + zend_string *ret = NULL; + if (U_FAILURE(error)) { intl_errors_set(RANGEFORMATTER_ERROR_P(obj), error, "Failed to format number range"); - } + } else { + ret = intl_charFromString(result, &error); - zend_string *ret = intl_charFromString(result, &error); + if (UNEXPECTED(ret == NULL)) { + if (U_SUCCESS(error)) { + error = U_ILLEGAL_ARGUMENT_ERROR; + } - if (U_FAILURE(error)) { - intl_errors_set(RANGEFORMATTER_ERROR_P(obj), error, "Failed to convert result to UTF-8"); + intl_errors_set(RANGEFORMATTER_ERROR_P(obj), error, "Failed to convert result to UTF-8"); + } } INTL_G(use_exceptions) = old_use_exception; INTL_G(error_level) = old_error_level; + if (UNEXPECTED(ret == NULL)) { + RETURN_THROWS(); + } + RETVAL_NEW_STR(ret); } diff --git a/ext/intl/tests/rangeformatter/rangeformatter_error_reset_scope.phpt b/ext/intl/tests/rangeformatter/rangeformatter_error_reset_scope.phpt new file mode 100644 index 000000000000..7fcd37a00c69 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_error_reset_scope.phpt @@ -0,0 +1,64 @@ +--TEST-- +IntlNumberRangeFormatter keeps the intl error state on a parameter error +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format([], 2); +} catch (TypeError $error) { + echo $error::class, ': ', $error->getMessage(), PHP_EOL; +} + +var_dump(intl_get_error_code() !== 0); + +try { + IntlNumberRangeFormatter::createFromSkeleton( + [], + 'en_US', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE + ); +} catch (TypeError $error) { + echo $error::class, ': ', $error->getMessage(), PHP_EOL; +} + +var_dump(intl_get_error_code() !== 0); + +$formatter->format(1, 2); + +var_dump(intl_get_error_code()); +var_dump($formatter->getErrorCode()); + +?> +--EXPECT-- +TypeError: IntlNumberRangeFormatter::format(): Argument #1 ($start) must be of type int|float, array given +bool(true) +TypeError: IntlNumberRangeFormatter::createFromSkeleton(): Argument #1 ($skeleton) must be of type string, array given +bool(true) +int(0) +int(0) diff --git a/ext/intl/tests/rangeformatter/rangeformatter_format_failure.phpt b/ext/intl/tests/rangeformatter/rangeformatter_format_failure.phpt new file mode 100644 index 000000000000..854d0f74b995 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_format_failure.phpt @@ -0,0 +1,54 @@ +--TEST-- +IntlNumberRangeFormatter::format() with a failing formatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(1, 2); +} catch (IntlException $exception) { + echo $exception::class, ': ', $exception->getMessage(), PHP_EOL; +} + +var_dump($formatter->getErrorCode() !== 0); +var_dump(str_starts_with( + $formatter->getErrorMessage(), + 'IntlNumberRangeFormatter::format(): Failed to format number range: ' +)); + +var_dump(intl_get_error_code() !== 0); + +$formatter = IntlNumberRangeFormatter::createFromSkeleton( + '', + 'en_US', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE +); + +var_dump($formatter->format(1, 2) !== ''); +var_dump($formatter->getErrorCode()); +var_dump($formatter->getErrorMessage()); + +?> +--EXPECT-- +IntlException: IntlNumberRangeFormatter::format(): Failed to format number range +bool(true) +bool(true) +bool(true) +bool(true) +int(0) +string(12) "U_ZERO_ERROR" From b6595ccc3e95979a6fdb7cd1619e100144c6fe74 Mon Sep 17 00:00:00 2001 From: Rob Landers Date: Mon, 10 Aug 2026 17:54:40 +0200 Subject: [PATCH 03/25] Update test file path for bug60771 (#22980) --- Zend/tests/bug60771.phpt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/tests/bug60771.phpt b/Zend/tests/bug60771.phpt index 119ae50ad4f8..7d08f55bf70d 100644 --- a/Zend/tests/bug60771.phpt +++ b/Zend/tests/bug60771.phpt @@ -2,9 +2,9 @@ test of larger than 8kb text file being parsed by require statement --FILE-- --EXPECT-- passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, passed, From 0d26c1ce637ac9c4f63c87c8aa8e923d69298c40 Mon Sep 17 00:00:00 2001 From: NickSdot <32384907+NickSdot@users.noreply.github.com> Date: Tue, 11 Aug 2026 00:05:06 +0700 Subject: [PATCH 04/25] CI: Select Windows test workers automatically (#22946) Removes the hard-coded -j2 from Windows CI so run-tests.php selects the worker count automatically --- .github/matrix.php | 1 + .github/workflows/test-suite.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/matrix.php b/.github/matrix.php index 7970442d7050..88e505d1f1eb 100644 --- a/.github/matrix.php +++ b/.github/matrix.php @@ -187,6 +187,7 @@ function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $re foreach ($branches as &$branch) { $php_version = $branch['version'][0] . '.' . $branch['version'][1]; $branch['jobs'] = select_jobs($repository, $trigger, $nightly, $labels, $php_version, $branch['ref'], $all_variations); + $branch['config']['default_run_test_jobs'] = version_compare($php_version, '8.6', '>=') ? '' : '-j2'; $branch['config']['ubuntu_version'] = version_compare($php_version, '8.5', '>=') ? '24.04' : '22.04'; } diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index c2b076059bc0..2046a3d816c8 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -857,7 +857,7 @@ jobs: PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }} THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}" INTRINSICS: "${{ matrix.zts && 'AVX2' || '' }}" - PARALLEL: -j2 + PARALLEL: ${{ matrix.asan && '-j2' || fromJson(inputs.branch).config.default_run_test_jobs }} OPCACHE: "${{ matrix.opcache && '1' || '0' }}" ASAN: "${{ matrix.asan && '1' || '0' }}" CLANG_TOOLSET: "${{ matrix.clang && '1' || '0' }}" From c2816be05a4cca04225bc397943f871f859df670 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 11 Aug 2026 01:09:08 +0800 Subject: [PATCH 05/25] Zend: Name map ptr chunk size constants (#23109) Let's prevent writing 4095 and 4096 as a magic number, its indeed confusing, instead use ZEND_MAP_PTR_CHUNK_MASK and ZEND_MAP_PTR_CHUNK_SIZE --- Zend/zend.c | 12 ++++++------ Zend/zend_map_ptr.h | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index b1ad3f4fe7f3..8643c248e6be 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -746,7 +746,7 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{ compiler_globals->internal_run_time_cache = NULL; if (compiler_globals->map_ptr_last || zend_map_ptr_static_size) { /* Allocate map_ptr table */ - compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096); + compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, ZEND_MAP_PTR_CHUNK_SIZE); void *base = pemalloc((zend_map_ptr_static_size + compiler_globals->map_ptr_size) * sizeof(void*), 1); compiler_globals->map_ptr_real_base = base; compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(base); @@ -2064,7 +2064,7 @@ ZEND_API void *zend_map_ptr_new(void) if (CG(map_ptr_last) >= CG(map_ptr_size)) { /* Grow map_ptr table */ - CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096); + CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, ZEND_MAP_PTR_CHUNK_SIZE); CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), (zend_map_ptr_static_size + CG(map_ptr_size)) * sizeof(void*), 1); CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base)); } @@ -2079,17 +2079,17 @@ ZEND_API void *zend_map_ptr_new_static(void) void **ptr; if (zend_map_ptr_static_last >= zend_map_ptr_static_size) { - zend_map_ptr_static_size += 4096; + zend_map_ptr_static_size += ZEND_MAP_PTR_CHUNK_SIZE; /* Grow map_ptr table */ void *new_base = pemalloc((zend_map_ptr_static_size + CG(map_ptr_size)) * sizeof(void*), 1); if (CG(map_ptr_real_base)) { - memcpy((void **)new_base + 4096, CG(map_ptr_real_base), (CG(map_ptr_last) + zend_map_ptr_static_size - 4096) * sizeof(void *)); + memcpy((void **)new_base + ZEND_MAP_PTR_CHUNK_SIZE, CG(map_ptr_real_base), (CG(map_ptr_last) + zend_map_ptr_static_size - ZEND_MAP_PTR_CHUNK_SIZE) * sizeof(void *)); pefree(CG(map_ptr_real_base), 1); } CG(map_ptr_real_base) = new_base; CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(new_base); } - ptr = (void**)CG(map_ptr_real_base) + (zend_map_ptr_static_last & 4095); + ptr = (void**)CG(map_ptr_real_base) + (zend_map_ptr_static_last & ZEND_MAP_PTR_CHUNK_MASK); *ptr = NULL; zend_map_ptr_static_last++; return ZEND_MAP_PTR_PTR2OFFSET(ptr); @@ -2102,7 +2102,7 @@ ZEND_API void zend_map_ptr_extend(size_t last) if (last >= CG(map_ptr_size)) { /* Grow map_ptr table */ - CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096); + CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, ZEND_MAP_PTR_CHUNK_SIZE); CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), (zend_map_ptr_static_size + CG(map_ptr_size)) * sizeof(void*), 1); CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base)); } diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h index af3b5178aa4a..47de0e8873b7 100644 --- a/Zend/zend_map_ptr.h +++ b/Zend/zend_map_ptr.h @@ -26,6 +26,8 @@ typedef struct _zend_string zend_string; #define ZEND_MAP_PTR_KIND_PTR_OR_OFFSET 1 #define ZEND_MAP_PTR_KIND ZEND_MAP_PTR_KIND_PTR_OR_OFFSET +#define ZEND_MAP_PTR_CHUNK_SIZE 4096 +#define ZEND_MAP_PTR_CHUNK_MASK (ZEND_MAP_PTR_CHUNK_SIZE - 1) #define ZEND_MAP_PTR(ptr) \ ptr ## __ptr @@ -71,7 +73,9 @@ typedef struct _zend_string zend_string; ((void*)(((uintptr_t)(real_base)) + zend_map_ptr_static_size * sizeof(void *) - 1)) /* Note: chunked like: [8192..12287][4096..8191][0..4095] */ #define ZEND_MAP_PTR_STATIC_NUM_TO_PTR(num) \ - ((void **)CG(map_ptr_real_base) + zend_map_ptr_static_size - ZEND_MM_ALIGNED_SIZE_EX((num) + 1, 4096) + ((num) & 4095)) + ((void **)CG(map_ptr_real_base) + zend_map_ptr_static_size \ + - ZEND_MM_ALIGNED_SIZE_EX((num) + 1, ZEND_MAP_PTR_CHUNK_SIZE) \ + + ((num) & ZEND_MAP_PTR_CHUNK_MASK)) #else # error "Unknown ZEND_MAP_PTR_KIND" #endif From a9ba369abe43a4947e4015171f0111c4a816a630 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 14:56:06 +0100 Subject: [PATCH 06/25] Zend: deprecate naming a function readonly RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_the_possibility_to_name_a_function_readonly --- .../readonly_as_fn_name_is_deprecated.phpt | 12 ++++++++++++ ...nly_as_fn_name_is_deprecated_namespaced.phpt | 14 ++++++++++++++ ..._as_fn_name_is_deprecated_throw_handler.phpt | 17 +++++++++++++++++ .../readonly_as_method_name_is_ok.phpt | 13 +++++++++++++ Zend/tests/grammar/readonly_function.phpt | 3 ++- Zend/zend_compile.c | 4 ++++ 6 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/functions/readonly_as_fn_name_is_deprecated.phpt create mode 100644 Zend/tests/functions/readonly_as_fn_name_is_deprecated_namespaced.phpt create mode 100644 Zend/tests/functions/readonly_as_fn_name_is_deprecated_throw_handler.phpt create mode 100644 Zend/tests/functions/readonly_as_method_name_is_ok.phpt diff --git a/Zend/tests/functions/readonly_as_fn_name_is_deprecated.phpt b/Zend/tests/functions/readonly_as_fn_name_is_deprecated.phpt new file mode 100644 index 000000000000..2ac975dcf654 --- /dev/null +++ b/Zend/tests/functions/readonly_as_fn_name_is_deprecated.phpt @@ -0,0 +1,12 @@ +--TEST-- +Naming a function readonly is deprecated +--FILE-- + +DONE +--EXPECTF-- +Deprecated: Calling a function “readonly” is deprecated in %s on line %d +DONE diff --git a/Zend/tests/functions/readonly_as_fn_name_is_deprecated_namespaced.phpt b/Zend/tests/functions/readonly_as_fn_name_is_deprecated_namespaced.phpt new file mode 100644 index 000000000000..f4b39d6c3e5a --- /dev/null +++ b/Zend/tests/functions/readonly_as_fn_name_is_deprecated_namespaced.phpt @@ -0,0 +1,14 @@ +--TEST-- +Naming a function readonly is deprecated +--FILE-- + +DONE +--EXPECTF-- +Deprecated: Calling a function “readonly” is deprecated in %s on line %d +DONE diff --git a/Zend/tests/functions/readonly_as_fn_name_is_deprecated_throw_handler.phpt b/Zend/tests/functions/readonly_as_fn_name_is_deprecated_throw_handler.phpt new file mode 100644 index 000000000000..428bd339d111 --- /dev/null +++ b/Zend/tests/functions/readonly_as_fn_name_is_deprecated_throw_handler.phpt @@ -0,0 +1,17 @@ +--TEST-- +Naming a function readonly is deprecated with an error handler elevating it to an exception +--FILE-- + +DONE +--EXPECTF-- +Deprecated: Calling a function “readonly” is deprecated in %s on line %d +DONE diff --git a/Zend/tests/functions/readonly_as_method_name_is_ok.phpt b/Zend/tests/functions/readonly_as_method_name_is_ok.phpt new file mode 100644 index 000000000000..373fa735365b --- /dev/null +++ b/Zend/tests/functions/readonly_as_method_name_is_ok.phpt @@ -0,0 +1,13 @@ +--TEST-- +Naming a function readonly is deprecated +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/grammar/readonly_function.phpt b/Zend/tests/grammar/readonly_function.phpt index 35102d36b9dc..c1592aa1fe8c 100644 --- a/Zend/tests/grammar/readonly_function.phpt +++ b/Zend/tests/grammar/readonly_function.phpt @@ -32,7 +32,8 @@ $b->readonly(); echo $b->readonly, "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Calling a function “readonly” is deprecated in %s on line %d Hi! Const hi! Static hi! diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 882b1bf990bf..92807513bc6a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8931,6 +8931,10 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, "__autoload() is no longer supported, use spl_autoload_register() instead"); } + if (zend_string_equals_literal_ci(unqualified_name, "readonly")) { + zend_error(E_DEPRECATED, "Calling a function “readonly” is deprecated"); + } + if (zend_string_equals_literal_ci(unqualified_name, "assert")) { zend_error(E_COMPILE_ERROR, "Defining a custom assert() function is not allowed, " From 7e0d5c75e7e03f3a9abe488a3df0ab893e36c740 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 15:05:55 +0100 Subject: [PATCH 07/25] standard: deprecate passing an object to array_walk{_recursive}() RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_array_parameter_of_array_walk_and_array_walk_recursive --- Zend/tests/exceptions/gh16188.phpt | 1 + Zend/tests/lazy_objects/array_walk.phpt | 1 + Zend/tests/property_hooks/gh18268.phpt | 3 ++- ext/ffi/tests/gh9697.phpt | 3 ++- ext/standard/array.c | 17 +++++++++++++++++ .../array/array_walk/array_walk_object1.phpt | 2 ++ .../array/array_walk/array_walk_objects.phpt | 3 +++ .../array_walk/array_walk_rec_objects.phpt | 3 +++ .../array_walk_recursive_object1.phpt | 2 ++ .../tests/array/array_walk/bug79839.phpt | 3 ++- 10 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Zend/tests/exceptions/gh16188.phpt b/Zend/tests/exceptions/gh16188.phpt index 4516f7cade90..2be2f991c8f3 100644 --- a/Zend/tests/exceptions/gh16188.phpt +++ b/Zend/tests/exceptions/gh16188.phpt @@ -16,6 +16,7 @@ printf("__toString:\n%s\n\n", $re); ?> ==DONE== --EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d getTraceAsString: #0 {main} diff --git a/Zend/tests/lazy_objects/array_walk.phpt b/Zend/tests/lazy_objects/array_walk.phpt index afee146025c9..3de8d6331a3c 100644 --- a/Zend/tests/lazy_objects/array_walk.phpt +++ b/Zend/tests/lazy_objects/array_walk.phpt @@ -26,6 +26,7 @@ var_dump($obj); ?> --EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d TypeError: Cannot assign string to reference held by property C::$a of type int lazy proxy object(C)#%d (1) { ["instance"]=> diff --git a/Zend/tests/property_hooks/gh18268.phpt b/Zend/tests/property_hooks/gh18268.phpt index 9836bb6d9627..78099923999d 100644 --- a/Zend/tests/property_hooks/gh18268.phpt +++ b/Zend/tests/property_hooks/gh18268.phpt @@ -19,5 +19,6 @@ array_walk($b, function (&$item) { }); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d int(42) diff --git a/ext/ffi/tests/gh9697.phpt b/ext/ffi/tests/gh9697.phpt index 7d19480e6944..0f82c8b43a26 100644 --- a/ext/ffi/tests/gh9697.phpt +++ b/ext/ffi/tests/gh9697.phpt @@ -10,5 +10,6 @@ $x = FFI::cdef()->new('int'); array_walk($x, function($x) { echo "test\n"; }); ?> DONE ---EXPECT-- +--EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d DONE diff --git a/ext/standard/array.c b/ext/standard/array.c index 51b1795b9111..91d3932516eb 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1518,6 +1518,14 @@ PHP_FUNCTION(array_walk) Z_PARAM_ZVAL(userdata) ZEND_PARSE_PARAMETERS_END(); + if (Z_TYPE_P(array) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + php_array_walk(&context, array, userdata, /* recursive */ false); RETURN_TRUE; } @@ -1537,6 +1545,15 @@ PHP_FUNCTION(array_walk_recursive) Z_PARAM_ZVAL(userdata) ZEND_PARSE_PARAMETERS_END(); + + if (Z_TYPE_P(array) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + php_array_walk(&context, array, userdata, /* recursive */ true); RETURN_TRUE; } diff --git a/ext/standard/tests/array/array_walk/array_walk_object1.phpt b/ext/standard/tests/array/array_walk/array_walk_object1.phpt index 7c700be11846..cd722f04abc1 100644 --- a/ext/standard/tests/array/array_walk/array_walk_object1.phpt +++ b/ext/standard/tests/array/array_walk/array_walk_object1.phpt @@ -38,6 +38,8 @@ echo "Done" ?> --EXPECTF-- *** Testing array_walk() : object functionality *** + +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d string(18) "%r\0%rMyClass%r\0%rpri_value" int(10) int(1) diff --git a/ext/standard/tests/array/array_walk/array_walk_objects.phpt b/ext/standard/tests/array/array_walk/array_walk_objects.phpt index 44b5b27e51e8..cc50ad38b9c2 100644 --- a/ext/standard/tests/array/array_walk/array_walk_objects.phpt +++ b/ext/standard/tests/array/array_walk/array_walk_objects.phpt @@ -33,10 +33,13 @@ try { echo "Done\n"; ?> --EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d string(3) "foo" string(3) "foo" string(3) "bar" string(3) "bar" + +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d string(13) "%r\0%rtest%r\0%rvar_pri" string(12) "test_private" string(10) "%r\0%r*%r\0%rvar_pro" diff --git a/ext/standard/tests/array/array_walk/array_walk_rec_objects.phpt b/ext/standard/tests/array/array_walk/array_walk_rec_objects.phpt index 91a97437d217..26082134f632 100644 --- a/ext/standard/tests/array/array_walk/array_walk_rec_objects.phpt +++ b/ext/standard/tests/array/array_walk/array_walk_rec_objects.phpt @@ -33,10 +33,13 @@ try { echo "Done\n"; ?> --EXPECTF-- +Deprecated: array_walk_recursive(): Passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead in %s on line %d string(3) "foo" string(3) "foo" string(3) "bar" string(3) "bar" + +Deprecated: array_walk_recursive(): Passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead in %s on line %d string(13) "%0test%0var_pri" string(12) "test_private" string(10) "%0*%0var_pro" diff --git a/ext/standard/tests/array/array_walk/array_walk_recursive_object1.phpt b/ext/standard/tests/array/array_walk/array_walk_recursive_object1.phpt index 9570bf8a02e2..023117b09edf 100644 --- a/ext/standard/tests/array/array_walk/array_walk_recursive_object1.phpt +++ b/ext/standard/tests/array/array_walk/array_walk_recursive_object1.phpt @@ -36,6 +36,8 @@ echo "Done" ?> --EXPECTF-- *** Testing array_walk_recursive() : object functionality *** + +Deprecated: array_walk_recursive(): Passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead in %s on line %d string(18) "%r\0%rMyClass%r\0%rpri_value" int(10) int(1) diff --git a/ext/standard/tests/array/array_walk/bug79839.phpt b/ext/standard/tests/array/array_walk/bug79839.phpt index 643604cb9b20..fe7db73c4683 100644 --- a/ext/standard/tests/array/array_walk/bug79839.phpt +++ b/ext/standard/tests/array/array_walk/bug79839.phpt @@ -18,7 +18,8 @@ try { var_dump($test); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: array_walk(): Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead in %s on line %d Cannot assign array to reference held by property Test::$prop of type int object(Test)#1 (1) { ["prop"]=> From f8c854e82faec850981a4a65e6c64a822ec580af Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 15:48:24 +0100 Subject: [PATCH 08/25] zlib: deprecate passing objects as array Implements RFCs: - https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_options_parameter_of_deflate_init_and_inflate_init - https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_as_parameters_to_the_zlibinflate_and_zlibdeflate_stream_filters --- .../tests/filter_broken_object_options.phpt | 5 +++- ext/zlib/tests/gh17745.phpt | 5 +++- ext/zlib/tests/gh17745_inflate.phpt | 23 +++++++++++++++ ext/zlib/tests/gh22142.phpt | 3 +- ext/zlib/tests/gh22142_inflate.phpt | 21 ++++++++++++++ ext/zlib/zlib.c | 28 +++++++++++++++++-- ext/zlib/zlib_filter.c | 24 ++++++++++------ 7 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 ext/zlib/tests/gh17745_inflate.phpt create mode 100644 ext/zlib/tests/gh22142_inflate.phpt diff --git a/ext/zlib/tests/filter_broken_object_options.phpt b/ext/zlib/tests/filter_broken_object_options.phpt index beb0fef9fb13..a43c85f36718 100644 --- a/ext/zlib/tests/filter_broken_object_options.phpt +++ b/ext/zlib/tests/filter_broken_object_options.phpt @@ -17,5 +17,8 @@ stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_WRITE, new Params); fwrite($fp, "Hello world, hopefully not broken\n"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: stream_filter_append(): Passing an object for filter parameters for zlib.deflate is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: stream_filter_append(): Passing an object for filter parameters for zlib.inflate is deprecated, call get_object_vars() first instead in %s on line %d Hello world, hopefully not broken diff --git a/ext/zlib/tests/gh17745.phpt b/ext/zlib/tests/gh17745.phpt index 64331269dcda..5e522ee96145 100644 --- a/ext/zlib/tests/gh17745.phpt +++ b/ext/zlib/tests/gh17745.phpt @@ -13,8 +13,11 @@ class Options { } var_dump(deflate_init(ZLIB_ENCODING_RAW, new Options)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d object(DeflateContext)#2 (0) { } + +Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d object(DeflateContext)#3 (0) { } diff --git a/ext/zlib/tests/gh17745_inflate.phpt b/ext/zlib/tests/gh17745_inflate.phpt new file mode 100644 index 000000000000..c87f0fbea9dd --- /dev/null +++ b/ext/zlib/tests/gh17745_inflate.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-17745 (zlib extension incorrectly handles object arguments) +--EXTENSIONS-- +zlib +--FILE-- +level = 3; +var_dump(inflate_init(ZLIB_ENCODING_RAW, $obj)); + +class Options { + public int $level = 3; +} +var_dump(inflate_init(ZLIB_ENCODING_RAW, new Options)); +?> +--EXPECTF-- +Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d +object(InflateContext)#2 (0) { +} + +Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d +object(InflateContext)#3 (0) { +} diff --git a/ext/zlib/tests/gh22142.phpt b/ext/zlib/tests/gh22142.phpt index 9bbb9332df30..481ffef342aa 100644 --- a/ext/zlib/tests/gh22142.phpt +++ b/ext/zlib/tests/gh22142.phpt @@ -16,5 +16,6 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d TypeError: deflate_init(): Argument #2 ($options) the value for option "level" must be of type int, null given diff --git a/ext/zlib/tests/gh22142_inflate.phpt b/ext/zlib/tests/gh22142_inflate.phpt new file mode 100644 index 000000000000..853099e4911d --- /dev/null +++ b/ext/zlib/tests/gh22142_inflate.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF) +--EXTENSIONS-- +zlib +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d +TypeError: inflate_init(): Argument #2 ($options) the value for option "window" must be of type int, null given diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 5b630d74c889..44ab23233ac8 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -881,12 +881,24 @@ PHP_FUNCTION(inflate_init) zend_long encoding, window = 15; char *dict = NULL; size_t dictlen = 0; + zval *options_zv = NULL; HashTable *options = (HashTable *) &zend_empty_array; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|A", &encoding, &options_zv)) { RETURN_THROWS(); } + if (options_zv) { + if (Z_TYPE_P(options_zv) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + options = HASH_OF(options_zv); + } + if (!zlib_get_long_option(options, ZEND_STRL("window"), &window)) { RETURN_THROWS(); } @@ -1100,12 +1112,24 @@ PHP_FUNCTION(deflate_init) zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY; char *dict = NULL; size_t dictlen = 0; + zval *options_zv = NULL; HashTable *options = (HashTable*)&zend_empty_array; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|A", &encoding, &options_zv)) { RETURN_THROWS(); } + if (options_zv) { + if (Z_TYPE_P(options_zv) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + options = HASH_OF(options_zv); + } + if (!zlib_get_long_option(options, ZEND_STRL("level"), &level)) { RETURN_THROWS(); } diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index 2d0e4fbb7fa4..4e6c1a54c0f9 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -361,6 +361,14 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f php_zlib_filter_data *data; int status; + if (filterparams && Z_TYPE_P(filterparams) == IS_OBJECT) { + php_error_docref("filters.compression", E_DEPRECATED, + "Passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead", filtername); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + } + if (php_stream_filter_parse_write_seek_mode(filterparams, &write_seekable) == FAILURE) { return NULL; } @@ -368,7 +376,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f /* Create this filter */ data = pecalloc(1, sizeof(php_zlib_filter_data), persistent); if (!data) { - php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", sizeof(php_zlib_filter_data)); + php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", sizeof(php_zlib_filter_data)); return NULL; } @@ -380,14 +388,14 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f data->strm.avail_out = data->outbuf_len = data->inbuf_len = 0x8000; data->strm.next_in = data->inbuf = (Bytef *) pemalloc(data->inbuf_len, persistent); if (!data->inbuf) { - php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", data->inbuf_len); + php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", data->inbuf_len); pefree(data, persistent); return NULL; } data->strm.avail_in = 0; data->strm.next_out = data->outbuf = (Bytef *) pemalloc(data->outbuf_len, persistent); if (!data->outbuf) { - php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", data->outbuf_len); + php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", data->outbuf_len); pefree(data->inbuf, persistent); pefree(data, persistent); return NULL; @@ -407,7 +415,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f /* log-2 base of history window (9 - 15) */ zend_long tmp = zval_get_long(tmpzval); if (tmp < -MAX_WBITS || tmp > MAX_WBITS + 32) { - php_error_docref(NULL, E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp); + php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp); } else { windowBits = tmp; } @@ -444,7 +452,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f /* Memory Level (1 - 9) */ tmp = zval_get_long(tmpzval); if (tmp < 1 || tmp > MAX_MEM_LEVEL) { - php_error_docref(NULL, E_WARNING, "Invalid parameter given for memory level (" ZEND_LONG_FMT ")", tmp); + php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for memory level (" ZEND_LONG_FMT ")", tmp); } else { memLevel = tmp; } @@ -454,7 +462,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f /* log-2 base of history window (9 - 15) */ tmp = zval_get_long(tmpzval); if (tmp < -MAX_WBITS || tmp > MAX_WBITS + 16) { - php_error_docref(NULL, E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp); + php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp); } else { windowBits = tmp; } @@ -475,13 +483,13 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f factory_setlevel: /* Set compression level within reason (-1 == default, 0 == none, 1-9 == least to most compression */ if (tmp < -1 || tmp > 9) { - php_error_docref(NULL, E_WARNING, "Invalid compression level specified. (" ZEND_LONG_FMT ")", tmp); + php_error_docref("filters.compression", E_WARNING, "Invalid compression level specified. (" ZEND_LONG_FMT ")", tmp); } else { level = tmp; } break; default: - php_error_docref(NULL, E_WARNING, "Invalid filter parameter, ignored"); + php_error_docref("filters.compression", E_WARNING, "Invalid filter parameter, ignored"); } } From 3fda4e9c187929cb95d0eec90c7fcd82e4161600 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 15:54:12 +0100 Subject: [PATCH 09/25] bz2: deprecate passing objects as array RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_as_parameters_to_the_bzip2decompress_and_bzip2compress_stream_filters --- ext/bz2/bz2_filter.c | 26 ++++++++++++++----- .../tests/filter_broken_object_options.phpt | 5 +++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index 845c11865f15..47fc9fc6e62f 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -402,12 +402,19 @@ static php_stream_filter *php_bz2_decompress_filter_create(zval *filter_params, && Z_TYPE_P(filter_params) != IS_ARRAY && Z_TYPE_P(filter_params) != IS_OBJECT )) { - php_error_docref(NULL, E_WARNING, + php_error_docref("filters.compression", E_WARNING, "Filter parameters for bzip2.decompress filter must be of type array|object|bool, %s given", zend_zval_type_name(filter_params) ); return NULL; } + if (Z_TYPE_P(filter_params) == IS_OBJECT) { + php_error_docref("filters.compression", E_DEPRECATED, + "Passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + } if (Z_TYPE_P(filter_params) == IS_TRUE || Z_TYPE_P(filter_params) == IS_FALSE) { small_footprint = Z_TYPE_P(filter_params) == IS_TRUE; @@ -448,12 +455,19 @@ static php_stream_filter *php_bz2_compress_filter_create(zval *filter_params, bo if (filter_params) { if (UNEXPECTED(Z_TYPE_P(filter_params) != IS_ARRAY && Z_TYPE_P(filter_params) != IS_OBJECT)) { - php_error_docref(NULL, E_WARNING, + php_error_docref("filters.compression", E_WARNING, "Filter parameters for bzip2.compress filter must be of type array|object, %s given", zend_zval_type_name(filter_params) ); return NULL; } + if (Z_TYPE_P(filter_params) == IS_OBJECT) { + php_error_docref("filters.compression", E_DEPRECATED, + "Passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead"); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + } const HashTable *filter_params_ht = HASH_OF(filter_params); /* TODO: convert php_stream_filter_parse_write_seek_mode() to take HashTable */ @@ -468,10 +482,10 @@ static php_stream_filter *php_bz2_compress_filter_create(zval *filter_params, bo /* How much memory to allocate (1 - 9) x 100kb */ zend_long blocks = zval_try_get_long(blocks_zv, &failed); if (UNEXPECTED(failed)) { - php_error_docref(NULL, E_WARNING, "Number of blocks parameter must be of type int, %s given", zend_zval_type_name(blocks_zv)); + php_error_docref("filters.compression", E_WARNING, "Number of blocks parameter must be of type int, %s given", zend_zval_type_name(blocks_zv)); return NULL; } else if (blocks < 1 || blocks > 9) { - php_error_docref(NULL, E_WARNING, "Number of blocks to allocate must be between 1 and 9, " ZEND_LONG_FMT " given", blocks); + php_error_docref("filters.compression", E_WARNING, "Number of blocks to allocate must be between 1 and 9, " ZEND_LONG_FMT " given", blocks); return NULL; } else { blockSize100k = (int) blocks; @@ -485,10 +499,10 @@ static php_stream_filter *php_bz2_compress_filter_create(zval *filter_params, bo /* Work Factor (0 - 250) */ zend_long work = zval_try_get_long(work_zv, &failed); if (UNEXPECTED(failed)) { - php_error_docref(NULL, E_WARNING, "Work factor parameter must be of type int, %s given", zend_zval_type_name(work_zv)); + php_error_docref("filters.compression", E_WARNING, "Work factor parameter must be of type int, %s given", zend_zval_type_name(work_zv)); return NULL; } else if (work < 0 || work > 250) { - php_error_docref(NULL, E_WARNING, "Work factor must be between 0 and 250, " ZEND_LONG_FMT " given", work); + php_error_docref("filters.compression", E_WARNING, "Work factor must be between 0 and 250, " ZEND_LONG_FMT " given", work); return NULL; } else { workFactor = (int) work; diff --git a/ext/bz2/tests/filter_broken_object_options.phpt b/ext/bz2/tests/filter_broken_object_options.phpt index 84e49a64ccb6..c24e2893c2b9 100644 --- a/ext/bz2/tests/filter_broken_object_options.phpt +++ b/ext/bz2/tests/filter_broken_object_options.phpt @@ -21,5 +21,8 @@ stream_filter_append($fp, 'bzip2.decompress', STREAM_FILTER_WRITE, new ParamsDec fwrite($fp, "Hello world, hopefully not broken\n"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: stream_filter_append(): Passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: stream_filter_append(): Passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead in %s on line %d Hello world, hopefully not broken From 7cc143235d2be7b989348d37f465860835833a25 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 16:23:31 +0100 Subject: [PATCH 10/25] mbstring: deprecate passing objects as vars to mb_convert_variables() RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_vars_parameter_of_mb_convert_variables --- ext/mbstring/mbstring.c | 23 ++++++++++++-- ext/mbstring/tests/gh16261.phpt | 3 +- ext/mbstring/tests/mb_convert_variables.phpt | 18 ++++++++++- .../mb_convert_variables_invalid_types.phpt | 30 +++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 ext/mbstring/tests/mb_convert_variables_invalid_types.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index b475b83e02f3..4059d8d35fd1 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3820,7 +3820,7 @@ static bool mb_recursive_find_strings(zval *var, const unsigned char **val_list, return false; } -static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_encoding, const mbfl_encoding* to_encoding) +static bool mb_recursive_convert_variable(uint32_t arg_num, zval *var, const mbfl_encoding* from_encoding, const mbfl_encoding* to_encoding) { zval *entry, *orig_var; @@ -3836,6 +3836,15 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e zval_ptr_dtor(orig_var); ZVAL_STR(orig_var, ret); } else if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) { + if (Z_TYPE_P(var) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #%" PRIu32 " $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead", + arg_num + ); + if (UNEXPECTED(EG(exception))) { + return true; + } + } HashTable *ht = HASH_OF(var); HashTable *orig_ht = ht; @@ -3872,7 +3881,7 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e } } - if (mb_recursive_convert_variable(entry, from_encoding, to_encoding)) { + if (mb_recursive_convert_variable(arg_num, entry, from_encoding, to_encoding)) { if (ht && ht != orig_ht) { GC_TRY_UNPROTECT_RECURSION(ht); } @@ -3890,6 +3899,14 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e if (orig_ht) { GC_TRY_UNPROTECT_RECURSION(orig_ht); } + } else if (Z_TYPE_P(var) != IS_UNDEF) { /* Ignore unset properties */ + php_error_docref(NULL, E_WARNING, + "Argument #%" PRIu32 " must be of type string|array|object or only contain entries of type string|array|object, %s given", + arg_num, zend_zval_type_name(var) + ); + if (UNEXPECTED(EG(exception))) { + return true; + } } return false; @@ -3985,7 +4002,7 @@ PHP_FUNCTION(mb_convert_variables) for (size_t n = 0; n < argc; n++) { zval *zv = &args[n]; ZVAL_DEREF(zv); - if (mb_recursive_convert_variable(zv, from_encoding, to_encoding)) { + if (mb_recursive_convert_variable(n + 3, zv, from_encoding, to_encoding)) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot handle recursive references"); } diff --git a/ext/mbstring/tests/gh16261.phpt b/ext/mbstring/tests/gh16261.phpt index 3573bd191c63..1fbbc5c208c9 100644 --- a/ext/mbstring/tests/gh16261.phpt +++ b/ext/mbstring/tests/gh16261.phpt @@ -26,7 +26,8 @@ mb_convert_variables("EUC-JP", "Shift_JIS", $test->x); var_dump($test, $test2); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d object(Test)#1 (2) { ["x"]=> string(5) "hello" diff --git a/ext/mbstring/tests/mb_convert_variables.phpt b/ext/mbstring/tests/mb_convert_variables.phpt index 2eb45946b5e8..7558bded048d 100644 --- a/ext/mbstring/tests/mb_convert_variables.phpt +++ b/ext/mbstring/tests/mb_convert_variables.phpt @@ -173,7 +173,7 @@ var_dump(mb_convert_variables('UTF-8', 'UTF7-IMAP,UTF-8', $bad_utf7imap)); var_dump($bad_utf7imap); ?> ---EXPECT-- +--EXPECTF-- == SCALAR TEST == SJIS c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 @@ -191,21 +191,37 @@ c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccb EUC-JP c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 == OBJECT TEST == + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d EUC-JP c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d EUC-JP c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 == SCALAR, ARRAY AND OBJECT TEST == + +Deprecated: mb_convert_variables(): Passing an object for argument #7 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d EUC-JP c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 == DEEPLY NESTED OBJECT/ARRAY TEST == + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d UTF-8 42004c0041004800 == INVALID STRING ENCODING TEST == + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d 2500 # of illegal characters detected: 1 + +Deprecated: mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead in %s on line %d 2600 # of illegal characters detected: 1 == ENCODING AUTO-DETECTION TEST == diff --git a/ext/mbstring/tests/mb_convert_variables_invalid_types.phpt b/ext/mbstring/tests/mb_convert_variables_invalid_types.phpt new file mode 100644 index 000000000000..70972f042130 --- /dev/null +++ b/ext/mbstring/tests/mb_convert_variables_invalid_types.phpt @@ -0,0 +1,30 @@ +--TEST-- +mb_convert_variables(): $vars which are not string|array|object +--EXTENSIONS-- +mbstring +--FILE-- +getMessage(), PHP_EOL; +} +try { + var_dump( mb_convert_variables('UTF-8', 'EUC-JP', $a)); +} catch (\ValueError $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Warning: mb_convert_variables(): Argument #3 must be of type string|array|object or only contain entries of type string|array|object, int given in %s on line %d + +Warning: mb_convert_variables(): Argument #4 must be of type string|array|object or only contain entries of type string|array|object, int given in %s on line %d +string(6) "EUC-JP" + +Warning: mb_convert_variables(): Argument #3 must be of type string|array|object or only contain entries of type string|array|object, int given in %s on line %d +string(6) "EUC-JP" From 0b14af3b980ba5f4b3a027c9f8418f6eee092c13 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 17:23:27 +0100 Subject: [PATCH 11/25] standard: deprecate aliases with non canonical type name Fix tests using non canonical versions and improve existing tests. RFC: - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_double - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_integer - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_long - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_doubleval --- .../union_types/incdec_prop.phpt | 16 +- Zend/zend_compile.c | 13 +- ext/date/tests/strtotime-mysql-64bit.phpt | 2 +- ext/date/tests/strtotime-mysql.phpt | 2 +- ext/date/tests/strtotime3-64bit.phpt | 2 +- ext/date/tests/strtotime3.phpt | 2 +- ext/filter/tests/046.phpt | 10 +- ext/filter/tests/047.phpt | 6 +- ext/filter/tests/048.phpt | 6 +- ext/pgsql/tests/20pg_get_pid.phpt | 2 +- ext/posix/tests/posix_getsid.phpt | 2 +- ext/spl/tests/regexiterator_getpregflags.phpt | 4 +- ext/standard/basic_functions.stub.php | 4 + ext/standard/basic_functions_arginfo.h | 38 +- ext/standard/basic_functions_decl.h | 8 +- .../tests/general_functions/doubleval.phpt | 50 ++ .../tests/general_functions/floatval.phpt | 171 ------- .../general_functions/floatval_basic.phpt | 117 +---- .../floatval_variation1.phpt | 88 +--- .../tests/general_functions/is_float.phpt | 299 +----------- .../general_functions/is_float_64bit.phpt | 333 -------------- .../general_functions/is_float_alias.phpt | 12 + .../tests/general_functions/is_int.phpt | 422 ++--------------- .../tests/general_functions/is_int_64bit.phpt | 427 ------------------ .../general_functions/is_int_aliases.phpt | 16 + 25 files changed, 242 insertions(+), 1810 deletions(-) create mode 100644 ext/standard/tests/general_functions/doubleval.phpt delete mode 100644 ext/standard/tests/general_functions/floatval.phpt delete mode 100644 ext/standard/tests/general_functions/is_float_64bit.phpt create mode 100644 ext/standard/tests/general_functions/is_float_alias.phpt delete mode 100644 ext/standard/tests/general_functions/is_int_64bit.phpt create mode 100644 ext/standard/tests/general_functions/is_int_aliases.phpt diff --git a/Zend/tests/type_declarations/union_types/incdec_prop.phpt b/Zend/tests/type_declarations/union_types/incdec_prop.phpt index dde6f595264a..7b61fc9fe60c 100644 --- a/Zend/tests/type_declarations/union_types/incdec_prop.phpt +++ b/Zend/tests/type_declarations/union_types/incdec_prop.phpt @@ -13,40 +13,40 @@ class Test { $test = new Test; $test->prop = PHP_INT_MAX; $x = $test->prop++; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MAX; $x = ++$test->prop; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MIN; $x = $test->prop--; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MIN; $x = --$test->prop; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test = new Test; $test->prop = PHP_INT_MAX; $r =& $test->prop; $x = $test->prop++; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MAX; $x = ++$test->prop; $r =& $test->prop; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MIN; $x = $test->prop--; $r =& $test->prop; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); $test->prop = PHP_INT_MIN; $x = --$test->prop; $r =& $test->prop; -var_dump(is_double($test->prop)); +var_dump(is_float($test->prop)); /* Incrementing a non-int|float property past int min/max is an error, * even if the result of the overflow (a float) would technically be allowed diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 92807513bc6a..cac60319a0af 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5387,14 +5387,9 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string * return zend_compile_func_typecheck(result, args, IS_NULL); } else if (zend_string_equals_literal(lcname, "is_bool")) { return zend_compile_func_typecheck(result, args, _IS_BOOL); - } else if (zend_string_equals_literal(lcname, "is_long") - || zend_string_equals_literal(lcname, "is_int") - || zend_string_equals_literal(lcname, "is_integer") - ) { + } else if (zend_string_equals_literal(lcname, "is_int")) { return zend_compile_func_typecheck(result, args, IS_LONG); - } else if (zend_string_equals_literal(lcname, "is_float") - || zend_string_equals_literal(lcname, "is_double") - ) { + } else if (zend_string_equals_literal(lcname, "is_float")) { return zend_compile_func_typecheck(result, args, IS_DOUBLE); } else if (zend_string_equals_literal(lcname, "is_string")) { return zend_compile_func_typecheck(result, args, IS_STRING); @@ -5410,9 +5405,7 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string * return zend_compile_func_cast(result, args, _IS_BOOL); } else if (zend_string_equals_literal(lcname, "intval")) { return zend_compile_func_cast(result, args, IS_LONG); - } else if (zend_string_equals_literal(lcname, "floatval") - || zend_string_equals_literal(lcname, "doubleval") - ) { + } else if (zend_string_equals_literal(lcname, "floatval")) { return zend_compile_func_cast(result, args, IS_DOUBLE); } else if (zend_string_equals_literal(lcname, "strval")) { return zend_compile_func_cast(result, args, IS_STRING); diff --git a/ext/date/tests/strtotime-mysql-64bit.phpt b/ext/date/tests/strtotime-mysql-64bit.phpt index ddf1dfff3fdf..ddc270cb9b16 100644 --- a/ext/date/tests/strtotime-mysql-64bit.phpt +++ b/ext/date/tests/strtotime-mysql-64bit.phpt @@ -14,7 +14,7 @@ $d[] = '20800410101010'; // overflow.. foreach($d as $date) { $time = strtotime($date); - if (is_integer($time)) { + if (is_int($time)) { var_dump(date('r', $time)); } else { var_dump($time); diff --git a/ext/date/tests/strtotime-mysql.phpt b/ext/date/tests/strtotime-mysql.phpt index c51f63f1323b..629165aa8733 100644 --- a/ext/date/tests/strtotime-mysql.phpt +++ b/ext/date/tests/strtotime-mysql.phpt @@ -14,7 +14,7 @@ $d[] = '20800410101010'; // overflow.. foreach($d as $date) { $time = strtotime($date); - if (is_integer($time)) { + if (is_int($time)) { var_dump(date('r', $time)); } else { var_dump($time); diff --git a/ext/date/tests/strtotime3-64bit.phpt b/ext/date/tests/strtotime3-64bit.phpt index c4f87c3b1a6a..d9dff3bc484d 100644 --- a/ext/date/tests/strtotime3-64bit.phpt +++ b/ext/date/tests/strtotime3-64bit.phpt @@ -36,7 +36,7 @@ $strs = array( foreach ($strs as $str) { $t = strtotime($str, $time); - if (is_integer($t)) { + if (is_int($t)) { var_dump(date(DATE_RFC2822, $t)); } else { var_dump($t); diff --git a/ext/date/tests/strtotime3.phpt b/ext/date/tests/strtotime3.phpt index 763b77a07da9..c96e07ca26e5 100644 --- a/ext/date/tests/strtotime3.phpt +++ b/ext/date/tests/strtotime3.phpt @@ -36,7 +36,7 @@ $strs = array( foreach ($strs as $str) { $t = strtotime($str, $time); - if (is_integer($t)) { + if (is_int($t)) { var_dump(date(DATE_RFC2822, $t)); } else { var_dump($t); diff --git a/ext/filter/tests/046.phpt b/ext/filter/tests/046.phpt index 295369e56f5f..ee95f5494ed6 100644 --- a/ext/filter/tests/046.phpt +++ b/ext/filter/tests/046.phpt @@ -24,7 +24,7 @@ default: function test_validation($val, $msg) { $f = filter_var($val, FILTER_VALIDATE_INT); echo "$msg filtered: "; var_dump($f); // filtered value (or false) - echo "$msg is_long: "; var_dump(is_long($f)); // test validation + echo "$msg is_int: "; var_dump(is_int($f)); // test validation echo "$msg equal: "; var_dump($val == $f); // test equality of result } @@ -36,14 +36,14 @@ test_validation($underflow, "underflow"); ?> --EXPECTF-- max filtered: int(%d) -max is_long: bool(true) +max is_int: bool(true) max equal: bool(true) overflow filtered: bool(false) -overflow is_long: bool(false) +overflow is_int: bool(false) overflow equal: bool(false) min filtered: int(-%d) -min is_long: bool(true) +min is_int: bool(true) min equal: bool(true) underflow filtered: bool(false) -underflow is_long: bool(false) +underflow is_int: bool(false) underflow equal: bool(false) diff --git a/ext/filter/tests/047.phpt b/ext/filter/tests/047.phpt index 763b64e837ed..76471e827628 100644 --- a/ext/filter/tests/047.phpt +++ b/ext/filter/tests/047.phpt @@ -19,13 +19,13 @@ function octal_inc($s) { $s = sprintf("%o", PHP_INT_MAX); -var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); +var_dump(is_int(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); $s = octal_inc($s); -var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); +var_dump(is_int(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); $s = sprintf("%o", ~0); -var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); +var_dump(is_int(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); $s = octal_inc($s); var_dump(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); diff --git a/ext/filter/tests/048.phpt b/ext/filter/tests/048.phpt index 7191726e3c97..a46d45455992 100644 --- a/ext/filter/tests/048.phpt +++ b/ext/filter/tests/048.phpt @@ -23,13 +23,13 @@ function hex_inc($s) { $s = sprintf("%x", PHP_INT_MAX); -var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); +var_dump(is_int(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); $s = hex_inc($s); -var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); +var_dump(is_int(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); $s = sprintf("%x", ~0); -var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); +var_dump(is_int(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); $s = hex_inc($s); var_dump(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); diff --git a/ext/pgsql/tests/20pg_get_pid.phpt b/ext/pgsql/tests/20pg_get_pid.phpt index 3cad32c838ff..5416afb476fa 100644 --- a/ext/pgsql/tests/20pg_get_pid.phpt +++ b/ext/pgsql/tests/20pg_get_pid.phpt @@ -13,7 +13,7 @@ include('inc/config.inc'); $db = pg_connect($conn_str); $pid = pg_get_pid($db); -is_integer($pid) ? print 'OK' : print 'NG'; +is_int($pid) ? print 'OK' : print 'NG'; ?> --EXPECT-- OK diff --git a/ext/posix/tests/posix_getsid.phpt b/ext/posix/tests/posix_getsid.phpt index fbf045711f97..fde7e237d699 100644 --- a/ext/posix/tests/posix_getsid.phpt +++ b/ext/posix/tests/posix_getsid.phpt @@ -14,7 +14,7 @@ echo "*** Testing posix_getsid() : function test ***\n"; $pid = posix_getpid(); echo "\n-- Testing posix_getsid() function with current process pid --\n"; -var_dump( is_long(posix_getsid($pid)) ); +var_dump( is_int(posix_getsid($pid)) ); ?> --EXPECT-- diff --git a/ext/spl/tests/regexiterator_getpregflags.phpt b/ext/spl/tests/regexiterator_getpregflags.phpt index 2fe492aebeb9..7e58dd47b416 100644 --- a/ext/spl/tests/regexiterator_getpregflags.phpt +++ b/ext/spl/tests/regexiterator_getpregflags.phpt @@ -26,8 +26,8 @@ $r = new TestRegexIterator(new myIterator, $rege); $r->setPregFlags(PREG_OFFSET_CAPTURE); -echo is_long($r->getPregFlags()); +var_dump(is_int($r->getPregFlags())); ?> --EXPECT-- -1 +bool(true) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 07e61957d191..ae3c9065cb18 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -3634,6 +3634,7 @@ function intval(mixed $value, int $base = 10): int {} function floatval(mixed $value): float {} /** @alias floatval */ +#[\Deprecated(message: "use floatval() instead", since: "8.6")] function doubleval(mixed $value): float {} /** @@ -3667,9 +3668,11 @@ function is_bool(mixed $value): bool {} function is_int(mixed $value): bool {} /** @alias is_int */ +#[\Deprecated(message: "use is_int() instead", since: "8.6")] function is_integer(mixed $value): bool {} /** @alias is_int */ +#[\Deprecated(message: "use is_int() instead", since: "8.6")] function is_long(mixed $value): bool {} /** @@ -3678,6 +3681,7 @@ function is_long(mixed $value): bool {} function is_float(mixed $value): bool {} /** @alias is_float */ +#[\Deprecated(message: "use is_float() instead", since: "8.6")] function is_double(mixed $value): bool {} /** diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index d24de1fef99d..91e1cb532768 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 0c8af3b78b3d6e1ee3e59c60363d0d941bea9faa + * Stub hash: 7a3bb062cb216bd28c1c97c44f2f611992c47063 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -3479,17 +3479,17 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(settype, arginfo_settype) ZEND_RAW_FENTRY("intval", zif_intval, arginfo_intval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("floatval", zif_floatval, arginfo_floatval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) - ZEND_RAW_FENTRY("doubleval", zif_floatval, arginfo_doubleval, 0, NULL, NULL) + ZEND_RAW_FENTRY("doubleval", zif_floatval, arginfo_doubleval, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("boolval", zif_boolval, arginfo_boolval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("strval", zif_strval, arginfo_strval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("is_null", zif_is_null, arginfo_is_null, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("is_resource", zif_is_resource, arginfo_is_resource, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("is_bool", zif_is_bool, arginfo_is_bool, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("is_int", zif_is_int, arginfo_is_int, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) - ZEND_RAW_FENTRY("is_integer", zif_is_int, arginfo_is_integer, 0, NULL, NULL) - ZEND_RAW_FENTRY("is_long", zif_is_int, arginfo_is_long, 0, NULL, NULL) + ZEND_RAW_FENTRY("is_integer", zif_is_int, arginfo_is_integer, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("is_long", zif_is_int, arginfo_is_long, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("is_float", zif_is_float, arginfo_is_float, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) - ZEND_RAW_FENTRY("is_double", zif_is_float, arginfo_is_double, 0, NULL, NULL) + ZEND_RAW_FENTRY("is_double", zif_is_float, arginfo_is_double, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("is_numeric", zif_is_numeric, arginfo_is_numeric, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_is_numeric, NULL) ZEND_RAW_FENTRY("is_string", zif_is_string, arginfo_is_string, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("is_array", zif_is_array, arginfo_is_array, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) @@ -3974,6 +3974,34 @@ static void register_basic_functions_symbols(int module_number) attribute_Deprecated_func_socket_set_timeout_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); #endif + zend_attribute *attribute_Deprecated_func_doubleval_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "doubleval", sizeof("doubleval") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_doubleval_0_arg0_str = zend_string_init("use floatval() instead", strlen("use floatval() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_doubleval_0->args[0].value, attribute_Deprecated_func_doubleval_0_arg0_str); + attribute_Deprecated_func_doubleval_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_string *attribute_Deprecated_func_doubleval_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_doubleval_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + attribute_Deprecated_func_doubleval_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_is_integer_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_integer", sizeof("is_integer") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_is_integer_0_arg0_str = zend_string_init("use is_int() instead", strlen("use is_int() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_is_integer_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); + attribute_Deprecated_func_is_integer_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_integer_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + attribute_Deprecated_func_is_integer_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_is_long_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_long", sizeof("is_long") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); + attribute_Deprecated_func_is_long_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + attribute_Deprecated_func_is_long_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_is_double_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_double", sizeof("is_double") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_is_double_0_arg0_str = zend_string_init("use is_float() instead", strlen("use is_float() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_is_double_0->args[0].value, attribute_Deprecated_func_is_double_0_arg0_str); + attribute_Deprecated_func_is_double_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_double_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + attribute_Deprecated_func_is_double_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index 97d896e8bb6e..ac1e9843da28 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 0c8af3b78b3d6e1ee3e59c60363d0d941bea9faa */ + * Stub hash: 7a3bb062cb216bd28c1c97c44f2f611992c47063 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_0c8af3b78b3d6e1ee3e59c60363d0d941bea9faa_H -#define ZEND_BASIC_FUNCTIONS_DECL_0c8af3b78b3d6e1ee3e59c60363d0d941bea9faa_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H +#define ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H typedef enum zend_enum_SortDirection { ZEND_ENUM_SortDirection_Ascending = 1, @@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_0c8af3b78b3d6e1ee3e59c60363d0d941bea9faa_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H */ diff --git a/ext/standard/tests/general_functions/doubleval.phpt b/ext/standard/tests/general_functions/doubleval.phpt new file mode 100644 index 000000000000..a3e083501fbf --- /dev/null +++ b/ext/standard/tests/general_functions/doubleval.phpt @@ -0,0 +1,50 @@ +--TEST-- +Deprecated doubleval() alias +--INI-- +precision = 14 +--FILE-- + +--EXPECTF-- +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d +bool(true) + +Deprecated: Function doubleval() is deprecated since 8.6, use floatval() instead in %s on line %d + +Warning: Object of class stdClass could not be converted to float in %s on line %d + +Warning: Object of class stdClass could not be converted to float in %s on line %d +bool(true) diff --git a/ext/standard/tests/general_functions/floatval.phpt b/ext/standard/tests/general_functions/floatval.phpt deleted file mode 100644 index 9ff49bb01084..000000000000 --- a/ext/standard/tests/general_functions/floatval.phpt +++ /dev/null @@ -1,171 +0,0 @@ ---TEST-- -Testing floatval() and its alias doubleval() Functions ---FILE-- - ---EXPECTF-- -*** Testing floatval() with valid float values *** -float(0) -float(1) -float(-1) -float(1.234) -float(-1.234) -float(1200) -float(-1200) -float(10) -float(1050000) -float(100000) -float(-100000) -float(1.0E-5) -float(-0.1) -float(100000) -float(-100000) -float(100000) -float(-100000) -float(100000) -float(-100000) -float(5000000) -float(-5000000) - -*** Testing doubleval() with valid float values *** -float(0) -float(1) -float(-1) -float(1.234) -float(-1.234) -float(1200) -float(-1200) -float(10) -float(1050000) -float(100000) -float(-100000) -float(1.0E-5) -float(-0.1) -float(100000) -float(-100000) -float(100000) -float(-100000) -float(100000) -float(-100000) -float(5000000) -float(-5000000) - -*** Testing floatval() on non floating types *** - -Warning: A non-numeric value encountered in %s on line %d - -Warning: A non-numeric value encountered in %s on line %d -float(-2147483648) -float(2147483648) -float(3) -float(0) -float(1) -float(-1300) -float(0) -float(10) -float(10.2) -float(11) -float(11) -float(0) -float(1) -float(0) -float(0) - -*** Testing doubleval() on non floating types *** -float(-2147483648) -float(2147483648) -float(3) -float(0) -float(1) -float(-1300) -float(0) -float(10) -float(10.2) -float(11) -float(11) -float(0) -float(1) -float(0) -float(0) - -Done diff --git a/ext/standard/tests/general_functions/floatval_basic.phpt b/ext/standard/tests/general_functions/floatval_basic.phpt index d20d4dedfaaf..c6de09853c2b 100644 --- a/ext/standard/tests/general_functions/floatval_basic.phpt +++ b/ext/standard/tests/general_functions/floatval_basic.phpt @@ -1,33 +1,33 @@ --TEST-- -Testing floatval() and its alias doubleval() Functions +Testing floatval() with floats --INI-- -precision = 14 +precision=14 --FILE-- 0.0, - "1.0" => 1.0, - "-1.0" => -1.0, - "1.234" => 1.234, - "-1.234" => -1.234, - "1.2e3" => 1.2e3, - "-1.2e3" => -1.2e3, - "10.0000000000000000005" => 10.0000000000000000005, - "10.5e+5" => 10.5e+5, - "1e5" => 1e5, - "-1e5" => -1e5, - "1e5" => 1e-5, - "-1e-1" => -1e-1, - "1e+5" => 1e+5, - "-1e+5" =>-1e+5, - "1E5" => 1E5, - "-1E5" => -1E5, - "1E+5" => 1E+5, - "-1E5" => -1E+5, - ".5e+7" => .5e+7, - "-.5e+7" =>-.5e+7 -); +$valid_floats = [ + "0.0" => 0.0, + "1.0" => 1.0, + "-1.0" => -1.0, + "1.234" => 1.234, + "-1.234" => -1.234, + "1.2e3" => 1.2e3, + "-1.2e3" => -1.2e3, + "10.0000000000000000005" => 10.0000000000000000005, + "10.5e+5" => 10.5e+5, + "1e5" => 1e5, + "-1e5" => -1e5, + "1e5" => 1e-5, + "-1e-1" => -1e-1, + "1e+5" => 1e+5, + "-1e+5" =>-1e+5, + "1E5" => 1E5, + "-1E5" => -1E5, + "1E+5" => 1E+5, + "-1E5" => -1E+5, + ".5e+7" => .5e+7, + "-.5e+7" =>-.5e+7 +]; /* loop to check that floatval() recognizes different float values, expected output:float value for valid floating point number */ @@ -37,14 +37,6 @@ foreach ($valid_floats as $key => $value ) { var_dump( floatval($value) ); } -/* loop to check that doubleval() also recognizes different - float values, expected output:float value for valid floating point number */ -echo "\n*** Testing doubleval() with valid float values ***\n"; -foreach ($valid_floats as $key => $value ) { - echo "\n-- Iteration : $key -- \n"; - var_dump( doubleval($value) ); -} - ?> --EXPECT-- *** Testing floatval() with valid float values *** @@ -105,62 +97,3 @@ float(5000000) -- Iteration : -.5e+7 -- float(-5000000) - -*** Testing doubleval() with valid float values *** - --- Iteration : 0.0 -- -float(0) - --- Iteration : 1.0 -- -float(1) - --- Iteration : -1.0 -- -float(-1) - --- Iteration : 1.234 -- -float(1.234) - --- Iteration : -1.234 -- -float(-1.234) - --- Iteration : 1.2e3 -- -float(1200) - --- Iteration : -1.2e3 -- -float(-1200) - --- Iteration : 10.0000000000000000005 -- -float(10) - --- Iteration : 10.5e+5 -- -float(1050000) - --- Iteration : 1e5 -- -float(1.0E-5) - --- Iteration : -1e5 -- -float(-100000) - --- Iteration : -1e-1 -- -float(-0.1) - --- Iteration : 1e+5 -- -float(100000) - --- Iteration : -1e+5 -- -float(-100000) - --- Iteration : 1E5 -- -float(100000) - --- Iteration : -1E5 -- -float(-100000) - --- Iteration : 1E+5 -- -float(100000) - --- Iteration : .5e+7 -- -float(5000000) - --- Iteration : -.5e+7 -- -float(-5000000) diff --git a/ext/standard/tests/general_functions/floatval_variation1.phpt b/ext/standard/tests/general_functions/floatval_variation1.phpt index 032d089b01c4..1759691aa21b 100644 --- a/ext/standard/tests/general_functions/floatval_variation1.phpt +++ b/ext/standard/tests/general_functions/floatval_variation1.phpt @@ -1,25 +1,28 @@ --TEST-- -Testing floatval() and its alias doubleval() functions : usage variations - different data types as $y arg +Testing floatval() different data types as arg +--INI-- +precision=14 --FILE-- -2147483648, // max negative integer value - "2147483647" => 2147483648, // max positive integer value - "stream resource" => STDERR, - "\"0.0\"" => "0.0", // string - "\"1.0\"" => "1.0", - "\"-1.3e3\"" => "-1.3e3", - "\"bob-1.3e3\"" => "bob-1.3e3", - "\"10 Some dollars\"" => "10 Some dollars", - "\"10.2 Some Dollars\"" => "10.2 Some Dollars", - "\"10.0 dollar\" + 1" => "10.0 dollar" + 1, - "\"10.0 dollar\" + 1.0" => "10.0 dollar" + 1.0, - "\"\"" => "", - "true" => true, - "null" => null, - ); +$not_float_types = [ + "-2147483648" => -2147483648, // max negative integer value + "2147483647" => 2147483648, // max positive integer value + "stream resource" => STDERR, + "\"0.0\"" => "0.0", // string + "\"1.0\"" => "1.0", + "\"-1.3e3\"" => "-1.3e3", + "\"bob-1.3e3\"" => "bob-1.3e3", + "\"10 Some dollars\"" => "10 Some dollars", + "\"10.2 Some Dollars\"" => "10.2 Some Dollars", + "\"10.0 dollar\" + 1" => "10.0 dollar" + 1, + "\"10.0 dollar\" + 1.0" => "10.0 dollar" + 1.0, + "\"\"" => "", + "true" => true, + "false" => false, + "null" => null, +]; /* loop through the $not_float_types to see working of floatval() on non float types, expected output: float value valid floating point numbers */ echo "\n*** Testing floatval() on non floating types ***\n"; @@ -28,14 +31,6 @@ foreach ($not_float_types as $key => $type ) { var_dump( floatval($type) ); } -echo "\n*** Testing doubleval() on non floating types ***\n"; - -/* loop through the $not_float_types to see working of - doubleval() on non float types, expected output: float value valid floating point numbers */ -foreach ($not_float_types as $key => $type ) { - echo "\n-- Iteration : $key --\n"; - var_dump( doubleval($type) ); -} ?> --EXPECTF-- Warning: A non-numeric value encountered in %s on line %d @@ -83,49 +78,8 @@ float(0) -- Iteration : true -- float(1) --- Iteration : null -- -float(0) - -*** Testing doubleval() on non floating types *** - --- Iteration : -2147483648 -- -float(-2147483648) - --- Iteration : 2147483647 -- -float(2147483648) - --- Iteration : stream resource -- -float(3) - --- Iteration : "0.0" -- -float(0) - --- Iteration : "1.0" -- -float(1) - --- Iteration : "-1.3e3" -- -float(-1300) - --- Iteration : "bob-1.3e3" -- +-- Iteration : false -- float(0) --- Iteration : "10 Some dollars" -- -float(10) - --- Iteration : "10.2 Some Dollars" -- -float(10.2) - --- Iteration : "10.0 dollar" + 1 -- -float(11) - --- Iteration : "10.0 dollar" + 1.0 -- -float(11) - --- Iteration : "" -- -float(0) - --- Iteration : true -- -float(1) - -- Iteration : null -- float(0) diff --git a/ext/standard/tests/general_functions/is_float.phpt b/ext/standard/tests/general_functions/is_float.phpt index e951ebe633c4..38e08cb19c06 100644 --- a/ext/standard/tests/general_functions/is_float.phpt +++ b/ext/standard/tests/general_functions/is_float.phpt @@ -1,20 +1,12 @@ --TEST-- -Test is_float() & its is_double() alias ---SKIPIF-- - +Test is_float() --FILE-- --EXPECT-- -*** Testing is_float(), is_double() with float values*** --- Iteration 1 -- -bool(true) -bool(true) --- Iteration 2 -- -bool(true) -bool(true) --- Iteration 3 -- -bool(true) -bool(true) --- Iteration 4 -- -bool(true) -bool(true) --- Iteration 5 -- -bool(true) -bool(true) --- Iteration 6 -- -bool(true) -bool(true) --- Iteration 7 -- -bool(true) -bool(true) --- Iteration 8 -- -bool(true) -bool(true) --- Iteration 9 -- -bool(true) -bool(true) --- Iteration 10 -- -bool(true) -bool(true) --- Iteration 11 -- -bool(true) -bool(true) --- Iteration 12 -- -bool(true) -bool(true) --- Iteration 13 -- -bool(true) -bool(true) --- Iteration 14 -- -bool(true) -bool(true) --- Iteration 15 -- -bool(true) -bool(true) --- Iteration 16 -- -bool(true) -bool(true) --- Iteration 17 -- -bool(true) -bool(true) --- Iteration 18 -- -bool(true) -bool(true) --- Iteration 19 -- -bool(true) -bool(true) --- Iteration 20 -- -bool(true) -bool(true) --- Iteration 21 -- -bool(true) -bool(true) --- Iteration 22 -- -bool(true) -bool(true) --- Iteration 23 -- -bool(true) -bool(true) --- Iteration 24 -- -bool(true) -bool(true) --- Iteration 25 -- -bool(true) -bool(true) --- Iteration 26 -- -bool(true) -bool(true) --- Iteration 27 -- -bool(true) -bool(true) --- Iteration 28 -- -bool(true) -bool(true) --- Iteration 29 -- -bool(true) -bool(true) --- Iteration 30 -- -bool(true) -bool(true) - -*** Testing is_float(), is_double() with non float values *** ---Iteration 1-- -bool(false) -bool(false) ---Iteration 2-- -bool(false) -bool(false) ---Iteration 3-- -bool(false) -bool(false) ---Iteration 4-- -bool(false) -bool(false) ---Iteration 5-- -bool(false) -bool(false) ---Iteration 6-- -bool(false) -bool(false) ---Iteration 7-- -bool(false) -bool(false) ---Iteration 8-- -bool(false) -bool(false) ---Iteration 9-- -bool(false) -bool(false) ---Iteration 10-- -bool(false) -bool(false) ---Iteration 11-- -bool(false) -bool(false) ---Iteration 12-- -bool(false) -bool(false) ---Iteration 13-- -bool(false) -bool(false) ---Iteration 14-- -bool(false) -bool(false) ---Iteration 15-- -bool(false) -bool(false) ---Iteration 16-- -bool(false) -bool(false) ---Iteration 17-- -bool(false) -bool(false) ---Iteration 18-- -bool(false) -bool(false) ---Iteration 19-- -bool(false) -bool(false) ---Iteration 20-- -bool(false) -bool(false) ---Iteration 21-- -bool(false) -bool(false) ---Iteration 22-- -bool(false) -bool(false) ---Iteration 23-- -bool(false) -bool(false) ---Iteration 24-- -bool(false) -bool(false) ---Iteration 25-- -bool(false) -bool(false) ---Iteration 26-- -bool(false) -bool(false) ---Iteration 27-- -bool(false) -bool(false) ---Iteration 28-- -bool(false) -bool(false) ---Iteration 29-- -bool(false) -bool(false) ---Iteration 30-- -bool(false) -bool(false) ---Iteration 31-- -bool(false) -bool(false) ---Iteration 32-- -bool(false) -bool(false) ---Iteration 33-- -bool(false) -bool(false) ---Iteration 34-- -bool(false) -bool(false) ---Iteration 35-- -bool(false) -bool(false) ---Iteration 36-- -bool(false) -bool(false) ---Iteration 37-- -bool(false) -bool(false) Done diff --git a/ext/standard/tests/general_functions/is_float_64bit.phpt b/ext/standard/tests/general_functions/is_float_64bit.phpt deleted file mode 100644 index 93fcc0949bbe..000000000000 --- a/ext/standard/tests/general_functions/is_float_64bit.phpt +++ /dev/null @@ -1,333 +0,0 @@ ---TEST-- -Test is_float() & its is_double() alias ---SKIPIF-- - ---INI-- -precision=14 ---FILE-- - ---EXPECT-- -*** Testing is_float(), is_double() with float values*** --- Iteration 1 -- -bool(false) -bool(false) --- Iteration 2 -- -bool(false) -bool(false) --- Iteration 3 -- -bool(false) -bool(false) --- Iteration 4 -- -bool(false) -bool(false) --- Iteration 5 -- -bool(false) -bool(false) --- Iteration 6 -- -bool(false) -bool(false) --- Iteration 7 -- -bool(true) -bool(true) --- Iteration 8 -- -bool(true) -bool(true) --- Iteration 9 -- -bool(true) -bool(true) --- Iteration 10 -- -bool(true) -bool(true) --- Iteration 11 -- -bool(true) -bool(true) --- Iteration 12 -- -bool(true) -bool(true) --- Iteration 13 -- -bool(true) -bool(true) --- Iteration 14 -- -bool(true) -bool(true) --- Iteration 15 -- -bool(true) -bool(true) --- Iteration 16 -- -bool(true) -bool(true) --- Iteration 17 -- -bool(true) -bool(true) --- Iteration 18 -- -bool(true) -bool(true) --- Iteration 19 -- -bool(true) -bool(true) --- Iteration 20 -- -bool(true) -bool(true) --- Iteration 21 -- -bool(true) -bool(true) --- Iteration 22 -- -bool(true) -bool(true) --- Iteration 23 -- -bool(true) -bool(true) --- Iteration 24 -- -bool(true) -bool(true) --- Iteration 25 -- -bool(true) -bool(true) --- Iteration 26 -- -bool(true) -bool(true) --- Iteration 27 -- -bool(true) -bool(true) --- Iteration 28 -- -bool(true) -bool(true) --- Iteration 29 -- -bool(true) -bool(true) --- Iteration 30 -- -bool(true) -bool(true) - -*** Testing is_float(), is_double() with non float values *** ---Iteration 1-- -bool(false) -bool(false) ---Iteration 2-- -bool(false) -bool(false) ---Iteration 3-- -bool(false) -bool(false) ---Iteration 4-- -bool(false) -bool(false) ---Iteration 5-- -bool(false) -bool(false) ---Iteration 6-- -bool(false) -bool(false) ---Iteration 7-- -bool(false) -bool(false) ---Iteration 8-- -bool(false) -bool(false) ---Iteration 9-- -bool(false) -bool(false) ---Iteration 10-- -bool(false) -bool(false) ---Iteration 11-- -bool(false) -bool(false) ---Iteration 12-- -bool(false) -bool(false) ---Iteration 13-- -bool(false) -bool(false) ---Iteration 14-- -bool(false) -bool(false) ---Iteration 15-- -bool(false) -bool(false) ---Iteration 16-- -bool(false) -bool(false) ---Iteration 17-- -bool(false) -bool(false) ---Iteration 18-- -bool(false) -bool(false) ---Iteration 19-- -bool(false) -bool(false) ---Iteration 20-- -bool(false) -bool(false) ---Iteration 21-- -bool(false) -bool(false) ---Iteration 22-- -bool(false) -bool(false) ---Iteration 23-- -bool(false) -bool(false) ---Iteration 24-- -bool(false) -bool(false) ---Iteration 25-- -bool(false) -bool(false) ---Iteration 26-- -bool(false) -bool(false) ---Iteration 27-- -bool(false) -bool(false) ---Iteration 28-- -bool(false) -bool(false) ---Iteration 29-- -bool(false) -bool(false) ---Iteration 30-- -bool(false) -bool(false) ---Iteration 31-- -bool(false) -bool(false) ---Iteration 32-- -bool(false) -bool(false) ---Iteration 33-- -bool(false) -bool(false) ---Iteration 34-- -bool(false) -bool(false) ---Iteration 35-- -bool(false) -bool(false) ---Iteration 36-- -bool(false) -bool(false) ---Iteration 37-- -bool(false) -bool(false) -Done diff --git a/ext/standard/tests/general_functions/is_float_alias.phpt b/ext/standard/tests/general_functions/is_float_alias.phpt new file mode 100644 index 000000000000..db74a7e1298b --- /dev/null +++ b/ext/standard/tests/general_functions/is_float_alias.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test deprecated is_double aliases for is_float() + +--FILE-- + +--EXPECTF-- +Deprecated: Function is_double() is deprecated since 8.6, use is_float() instead in %s on line %d +bool(true) diff --git a/ext/standard/tests/general_functions/is_int.phpt b/ext/standard/tests/general_functions/is_int.phpt index 6dfcf9e1b422..3ec22708d803 100644 --- a/ext/standard/tests/general_functions/is_int.phpt +++ b/ext/standard/tests/general_functions/is_int.phpt @@ -1,62 +1,27 @@ --TEST-- -Test is_int() & it's FALIASes: is_long() & is_integer() functions ---SKIPIF-- - +Test is_int() --FILE-- "One", "two" => 2), - - /* strings */ - "", + null, + true, // boolean + false, '', - "0", '0', - "1", - '1', - "\x01", - '\x01', - "\01", - '\01', - 'string', - "string", - "true", - "FALSE", - 'false', - 'TRUE', - "NULL", - 'null', + '0.0', + '0.5', + '1e5', + '1.5e6_string', +]; - /* booleans */ - true, - false, - TRUE, - FALSE, - - /* undefined and unset vars */ - @$unset_var, - @$undefined_var -); -/* loop through the $not_int_types to see working of - is_int() on non integer types, expected output: bool(false) */ -$loop_counter = 1; foreach ($not_int_types as $type ) { - echo "--Iteration $loop_counter--\n"; $loop_counter++; - var_dump( is_int($type) ); - var_dump( is_integer($type) ); - var_dump( is_long($type) ); + if (is_int($type)) { + echo "Value $type should not be an int!\n"; + } } echo "Done\n"; -// close the resources -fclose($fp); -closedir($dfp); - ?> --EXPECT-- -*** Testing is_int(), is_integer() & is_long() with valid integer values *** ---Iteration 1-- -bool(true) -bool(true) -bool(true) ---Iteration 2-- -bool(true) -bool(true) -bool(true) ---Iteration 3-- -bool(true) -bool(true) -bool(true) ---Iteration 4-- -bool(false) -bool(false) -bool(false) ---Iteration 5-- -bool(true) -bool(true) -bool(true) ---Iteration 6-- -bool(true) -bool(true) -bool(true) ---Iteration 7-- -bool(true) -bool(true) -bool(true) ---Iteration 8-- -bool(true) -bool(true) -bool(true) ---Iteration 9-- -bool(true) -bool(true) -bool(true) ---Iteration 10-- -bool(true) -bool(true) -bool(true) ---Iteration 11-- -bool(true) -bool(true) -bool(true) ---Iteration 12-- -bool(false) -bool(false) -bool(false) ---Iteration 13-- -bool(true) -bool(true) -bool(true) ---Iteration 14-- -bool(true) -bool(true) -bool(true) ---Iteration 15-- -bool(true) -bool(true) -bool(true) ---Iteration 16-- -bool(true) -bool(true) -bool(true) ---Iteration 17-- -bool(false) -bool(false) -bool(false) ---Iteration 18-- -bool(true) -bool(true) -bool(true) - -*** Testing is_int(), is_integer() & is_long() with non integer values *** ---Iteration 1-- -bool(false) -bool(false) -bool(false) ---Iteration 2-- -bool(false) -bool(false) -bool(false) ---Iteration 3-- -bool(false) -bool(false) -bool(false) ---Iteration 4-- -bool(false) -bool(false) -bool(false) ---Iteration 5-- -bool(false) -bool(false) -bool(false) ---Iteration 6-- -bool(false) -bool(false) -bool(false) ---Iteration 7-- -bool(false) -bool(false) -bool(false) ---Iteration 8-- -bool(false) -bool(false) -bool(false) ---Iteration 9-- -bool(false) -bool(false) -bool(false) ---Iteration 10-- -bool(false) -bool(false) -bool(false) ---Iteration 11-- -bool(false) -bool(false) -bool(false) ---Iteration 12-- -bool(false) -bool(false) -bool(false) ---Iteration 13-- -bool(false) -bool(false) -bool(false) ---Iteration 14-- -bool(false) -bool(false) -bool(false) ---Iteration 15-- -bool(false) -bool(false) -bool(false) ---Iteration 16-- -bool(false) -bool(false) -bool(false) ---Iteration 17-- -bool(false) -bool(false) -bool(false) ---Iteration 18-- -bool(false) -bool(false) -bool(false) ---Iteration 19-- -bool(false) -bool(false) -bool(false) ---Iteration 20-- -bool(false) -bool(false) -bool(false) ---Iteration 21-- -bool(false) -bool(false) -bool(false) ---Iteration 22-- -bool(false) -bool(false) -bool(false) ---Iteration 23-- -bool(false) -bool(false) -bool(false) ---Iteration 24-- -bool(false) -bool(false) -bool(false) ---Iteration 25-- -bool(false) -bool(false) -bool(false) ---Iteration 26-- -bool(false) -bool(false) -bool(false) ---Iteration 27-- -bool(false) -bool(false) -bool(false) ---Iteration 28-- -bool(false) -bool(false) -bool(false) ---Iteration 29-- -bool(false) -bool(false) -bool(false) ---Iteration 30-- -bool(false) -bool(false) -bool(false) ---Iteration 31-- -bool(false) -bool(false) -bool(false) ---Iteration 32-- -bool(false) -bool(false) -bool(false) ---Iteration 33-- -bool(false) -bool(false) -bool(false) ---Iteration 34-- -bool(false) -bool(false) -bool(false) ---Iteration 35-- -bool(false) -bool(false) -bool(false) ---Iteration 36-- -bool(false) -bool(false) -bool(false) ---Iteration 37-- -bool(false) -bool(false) -bool(false) ---Iteration 38-- -bool(false) -bool(false) -bool(false) ---Iteration 39-- -bool(false) -bool(false) -bool(false) ---Iteration 40-- -bool(false) -bool(false) -bool(false) ---Iteration 41-- -bool(false) -bool(false) -bool(false) ---Iteration 42-- -bool(false) -bool(false) -bool(false) ---Iteration 43-- -bool(false) -bool(false) -bool(false) ---Iteration 44-- -bool(false) -bool(false) -bool(false) ---Iteration 45-- -bool(false) -bool(false) -bool(false) ---Iteration 46-- -bool(false) -bool(false) -bool(false) ---Iteration 47-- -bool(false) -bool(false) -bool(false) ---Iteration 48-- -bool(false) -bool(false) -bool(false) ---Iteration 49-- -bool(false) -bool(false) -bool(false) ---Iteration 50-- -bool(false) -bool(false) -bool(false) ---Iteration 51-- -bool(false) -bool(false) -bool(false) ---Iteration 52-- -bool(false) -bool(false) -bool(false) ---Iteration 53-- -bool(false) -bool(false) -bool(false) ---Iteration 54-- -bool(false) -bool(false) -bool(false) Done diff --git a/ext/standard/tests/general_functions/is_int_64bit.phpt b/ext/standard/tests/general_functions/is_int_64bit.phpt deleted file mode 100644 index 9676deea4cd1..000000000000 --- a/ext/standard/tests/general_functions/is_int_64bit.phpt +++ /dev/null @@ -1,427 +0,0 @@ ---TEST-- -Test is_int() & it's FALIASes: is_long() & is_integer() functions ---SKIPIF-- - ---INI-- -precision=14 ---FILE-- - "One", "two" => 2), - - /* strings */ - "", - '', - "0", - '0', - "1", - '1', - "\x01", - '\x01', - "\01", - '\01', - 'string', - "string", - "true", - "FALSE", - 'false', - 'TRUE', - "NULL", - 'null', - - /* booleans */ - true, - false, - TRUE, - FALSE, - - /* undefined and unset vars */ - @$unset_var, - @$undefined_var -); -/* loop through the $not_int_types to see working of - is_int() on non integer types, expected output: bool(false) */ -$loop_counter = 1; -foreach ($not_int_types as $type ) { - echo "--Iteration $loop_counter--\n"; $loop_counter++; - var_dump( is_int($type) ); - var_dump( is_integer($type) ); - var_dump( is_long($type) ); -} - -echo "Done\n"; -?> ---EXPECT-- -*** Testing is_int(), is_integer() & is_long() with valid integer values *** ---Iteration 1-- -bool(true) -bool(true) -bool(true) ---Iteration 2-- -bool(true) -bool(true) -bool(true) ---Iteration 3-- -bool(true) -bool(true) -bool(true) ---Iteration 4-- -bool(true) -bool(true) -bool(true) ---Iteration 5-- -bool(true) -bool(true) -bool(true) ---Iteration 6-- -bool(true) -bool(true) -bool(true) ---Iteration 7-- -bool(true) -bool(true) -bool(true) ---Iteration 8-- -bool(true) -bool(true) -bool(true) ---Iteration 9-- -bool(true) -bool(true) -bool(true) ---Iteration 10-- -bool(true) -bool(true) -bool(true) ---Iteration 11-- -bool(true) -bool(true) -bool(true) ---Iteration 12-- -bool(true) -bool(true) -bool(true) ---Iteration 13-- -bool(true) -bool(true) -bool(true) ---Iteration 14-- -bool(true) -bool(true) -bool(true) ---Iteration 15-- -bool(true) -bool(true) -bool(true) ---Iteration 16-- -bool(true) -bool(true) -bool(true) ---Iteration 17-- -bool(true) -bool(true) -bool(true) ---Iteration 18-- -bool(true) -bool(true) -bool(true) - -*** Testing is_int(), is_integer() & is_long() with non integer values *** ---Iteration 1-- -bool(true) -bool(true) -bool(true) ---Iteration 2-- -bool(true) -bool(true) -bool(true) ---Iteration 3-- -bool(true) -bool(true) -bool(true) ---Iteration 4-- -bool(true) -bool(true) -bool(true) ---Iteration 5-- -bool(true) -bool(true) -bool(true) ---Iteration 6-- -bool(true) -bool(true) -bool(true) ---Iteration 7-- -bool(false) -bool(false) -bool(false) ---Iteration 8-- -bool(false) -bool(false) -bool(false) ---Iteration 9-- -bool(false) -bool(false) -bool(false) ---Iteration 10-- -bool(false) -bool(false) -bool(false) ---Iteration 11-- -bool(false) -bool(false) -bool(false) ---Iteration 12-- -bool(false) -bool(false) -bool(false) ---Iteration 13-- -bool(false) -bool(false) -bool(false) ---Iteration 14-- -bool(false) -bool(false) -bool(false) ---Iteration 15-- -bool(false) -bool(false) -bool(false) ---Iteration 16-- -bool(false) -bool(false) -bool(false) ---Iteration 17-- -bool(false) -bool(false) -bool(false) ---Iteration 18-- -bool(false) -bool(false) -bool(false) ---Iteration 19-- -bool(false) -bool(false) -bool(false) ---Iteration 20-- -bool(false) -bool(false) -bool(false) ---Iteration 21-- -bool(false) -bool(false) -bool(false) ---Iteration 22-- -bool(false) -bool(false) -bool(false) ---Iteration 23-- -bool(false) -bool(false) -bool(false) ---Iteration 24-- -bool(false) -bool(false) -bool(false) ---Iteration 25-- -bool(false) -bool(false) -bool(false) ---Iteration 26-- -bool(false) -bool(false) -bool(false) ---Iteration 27-- -bool(false) -bool(false) -bool(false) ---Iteration 28-- -bool(false) -bool(false) -bool(false) ---Iteration 29-- -bool(false) -bool(false) -bool(false) ---Iteration 30-- -bool(false) -bool(false) -bool(false) ---Iteration 31-- -bool(false) -bool(false) -bool(false) ---Iteration 32-- -bool(false) -bool(false) -bool(false) ---Iteration 33-- -bool(false) -bool(false) -bool(false) ---Iteration 34-- -bool(false) -bool(false) -bool(false) ---Iteration 35-- -bool(false) -bool(false) -bool(false) ---Iteration 36-- -bool(false) -bool(false) -bool(false) ---Iteration 37-- -bool(false) -bool(false) -bool(false) ---Iteration 38-- -bool(false) -bool(false) -bool(false) ---Iteration 39-- -bool(false) -bool(false) -bool(false) ---Iteration 40-- -bool(false) -bool(false) -bool(false) ---Iteration 41-- -bool(false) -bool(false) -bool(false) ---Iteration 42-- -bool(false) -bool(false) -bool(false) ---Iteration 43-- -bool(false) -bool(false) -bool(false) ---Iteration 44-- -bool(false) -bool(false) -bool(false) ---Iteration 45-- -bool(false) -bool(false) -bool(false) ---Iteration 46-- -bool(false) -bool(false) -bool(false) ---Iteration 47-- -bool(false) -bool(false) -bool(false) ---Iteration 48-- -bool(false) -bool(false) -bool(false) ---Iteration 49-- -bool(false) -bool(false) -bool(false) ---Iteration 50-- -bool(false) -bool(false) -bool(false) ---Iteration 51-- -bool(false) -bool(false) -bool(false) ---Iteration 52-- -bool(false) -bool(false) -bool(false) ---Iteration 53-- -bool(false) -bool(false) -bool(false) ---Iteration 54-- -bool(false) -bool(false) -bool(false) -Done diff --git a/ext/standard/tests/general_functions/is_int_aliases.phpt b/ext/standard/tests/general_functions/is_int_aliases.phpt new file mode 100644 index 000000000000..f9a0b0da0d25 --- /dev/null +++ b/ext/standard/tests/general_functions/is_int_aliases.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test deprecated is_long/is_integer aliases for is_int() + +--FILE-- + +--EXPECTF-- +Deprecated: Function is_long() is deprecated since 8.6, use is_int() instead in %s on line %d +bool(true) + +Deprecated: Function is_integer() is deprecated since 8.6, use is_int() instead in %s on line %d +bool(true) From 22217b3bbb5e4c1cafbb77ca7e3cbbf9861d937f Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 5 Aug 2026 17:35:23 +0100 Subject: [PATCH 12/25] standard: deprecate strcoll and SORT_LOCALE_STRING RFCs: - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_strcoll - https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_sort_locale_string_flag_for_sort_functions --- ext/standard/basic_functions.stub.php | 2 ++ ext/standard/basic_functions_arginfo.h | 30 ++++++++++++++----- ext/standard/basic_functions_decl.h | 8 ++--- .../tests/array/sort/locale_sort.phpt | 3 +- ext/standard/tests/strings/strcoll.phpt | 3 +- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index ae3c9065cb18..fb7c5b90fdb8 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -78,6 +78,7 @@ * @var int * @cvalue PHP_SORT_LOCALE_STRING */ +#[\Deprecated(message: "use one of the Collator::*sort*() methods instead", since: "8.6")] const SORT_LOCALE_STRING = UNKNOWN; /** * @var int @@ -2319,6 +2320,7 @@ function strcspn(string $string, string $characters, int $offset = 0, ?int $leng function nl_langinfo(int $item): string|false {} #endif +#[\Deprecated(message: "use Collator::compare() instead", since: "8.6")] function strcoll(string $string1, string $string2): int {} /** diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 91e1cb532768..c352ef20a40a 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 7a3bb062cb216bd28c1c97c44f2f611992c47063 + * Stub hash: 21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -3158,7 +3158,7 @@ static const zend_function_entry ext_functions[] = { #if defined(HAVE_NL_LANGINFO) ZEND_FE(nl_langinfo, arginfo_nl_langinfo) #endif - ZEND_FE(strcoll, arginfo_strcoll) + ZEND_RAW_FENTRY("strcoll", zif_strcoll, arginfo_strcoll, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("trim", zif_trim, arginfo_trim, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_trim, NULL) ZEND_RAW_FENTRY("rtrim", zif_rtrim, arginfo_rtrim, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("chop", zif_rtrim, arginfo_chop, 0, NULL, NULL) @@ -3550,7 +3550,7 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("SORT_REGULAR", PHP_SORT_REGULAR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_NUMERIC", PHP_SORT_NUMERIC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_STRING", PHP_SORT_STRING, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("SORT_LOCALE_STRING", PHP_SORT_LOCALE_STRING, CONST_PERSISTENT); + zend_constant *const_SORT_LOCALE_STRING = REGISTER_LONG_CONSTANT("SORT_LOCALE_STRING", PHP_SORT_LOCALE_STRING, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("SORT_NATURAL", PHP_SORT_NATURAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_FLAG_CASE", PHP_SORT_FLAG_CASE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CASE_LOWER", PHP_CASE_LOWER, CONST_PERSISTENT); @@ -3948,6 +3948,14 @@ static void register_basic_functions_symbols(int module_number) ZVAL_STR(&attribute_Deprecated_func_assert_options_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_func_assert_options_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_func_strcoll_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "strcoll", sizeof("strcoll") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_strcoll_0_arg0_str = zend_string_init("use Collator::compare() instead", strlen("use Collator::compare() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_strcoll_0->args[0].value, attribute_Deprecated_func_strcoll_0_arg0_str); + attribute_Deprecated_func_strcoll_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_string *attribute_Deprecated_func_strcoll_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_strcoll_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + attribute_Deprecated_func_strcoll_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_func_utf8_encode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_encode", sizeof("utf8_encode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_utf8_encode_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); @@ -3978,30 +3986,36 @@ static void register_basic_functions_symbols(int module_number) zend_string *attribute_Deprecated_func_doubleval_0_arg0_str = zend_string_init("use floatval() instead", strlen("use floatval() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_doubleval_0->args[0].value, attribute_Deprecated_func_doubleval_0_arg0_str); attribute_Deprecated_func_doubleval_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - zend_string *attribute_Deprecated_func_doubleval_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); - ZVAL_STR(&attribute_Deprecated_func_doubleval_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_doubleval_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); attribute_Deprecated_func_doubleval_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_integer_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_integer", sizeof("is_integer") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_func_is_integer_0_arg0_str = zend_string_init("use is_int() instead", strlen("use is_int() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_is_integer_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); attribute_Deprecated_func_is_integer_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_integer_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_integer_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); attribute_Deprecated_func_is_integer_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_long_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_long", sizeof("is_long") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); attribute_Deprecated_func_is_long_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); attribute_Deprecated_func_is_long_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_double_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_double", sizeof("is_double") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_func_is_double_0_arg0_str = zend_string_init("use is_float() instead", strlen("use is_float() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_is_double_0->args[0].value, attribute_Deprecated_func_is_double_0_arg0_str); attribute_Deprecated_func_is_double_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_double_0->args[1].value, attribute_Deprecated_func_doubleval_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_double_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); attribute_Deprecated_func_is_double_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_const_SORT_LOCALE_STRING_0 = zend_add_global_constant_attribute(const_SORT_LOCALE_STRING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_const_SORT_LOCALE_STRING_0_arg0_str = zend_string_init("use one of the Collator::*sort*() methods instead", strlen("use one of the Collator::*sort*() methods instead"), 1); + ZVAL_STR(&attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[0].value, attribute_Deprecated_const_SORT_LOCALE_STRING_0_arg0_str); + attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR_COPY(&attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index ac1e9843da28..159d30b2c002 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 7a3bb062cb216bd28c1c97c44f2f611992c47063 */ + * Stub hash: 21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H -#define ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H +#define ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H typedef enum zend_enum_SortDirection { ZEND_ENUM_SortDirection_Ascending = 1, @@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_7a3bb062cb216bd28c1c97c44f2f611992c47063_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H */ diff --git a/ext/standard/tests/array/sort/locale_sort.phpt b/ext/standard/tests/array/sort/locale_sort.phpt index 2caccce78eb4..abbe9e5c068a 100644 --- a/ext/standard/tests/array/sort/locale_sort.phpt +++ b/ext/standard/tests/array/sort/locale_sort.phpt @@ -29,7 +29,8 @@ $table = array("AB" => "Alberta", asort($table, SORT_LOCALE_STRING); var_dump($table); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Constant SORT_LOCALE_STRING is deprecated since 8.6, use one of the Collator::*sort*() methods instead in %s on line %d array(13) { ["AB"]=> string(7) "Alberta" diff --git a/ext/standard/tests/strings/strcoll.phpt b/ext/standard/tests/strings/strcoll.phpt index d1d3df11fc18..2d36c0e82d89 100644 --- a/ext/standard/tests/strings/strcoll.phpt +++ b/ext/standard/tests/strings/strcoll.phpt @@ -16,5 +16,6 @@ if($result > 0) { echo "Pass\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function strcoll() is deprecated since 8.6, use Collator::compare() instead in %s on line %d Pass From 75abe1c654c33a440a56b7f4cb4695af413d07b7 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 6 Aug 2026 18:25:19 +0100 Subject: [PATCH 13/25] Zend: move builtin function tests into subfolder --- Zend/tests/{ => builtin_functions}/builtin_functions_basic.phpt | 0 .../{ => builtin_functions}/builtin_in_write_context_error1.phpt | 0 .../{ => builtin_functions}/builtin_in_write_context_error2.phpt | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename Zend/tests/{ => builtin_functions}/builtin_functions_basic.phpt (100%) rename Zend/tests/{ => builtin_functions}/builtin_in_write_context_error1.phpt (100%) rename Zend/tests/{ => builtin_functions}/builtin_in_write_context_error2.phpt (100%) diff --git a/Zend/tests/builtin_functions_basic.phpt b/Zend/tests/builtin_functions/builtin_functions_basic.phpt similarity index 100% rename from Zend/tests/builtin_functions_basic.phpt rename to Zend/tests/builtin_functions/builtin_functions_basic.phpt diff --git a/Zend/tests/builtin_in_write_context_error1.phpt b/Zend/tests/builtin_functions/builtin_in_write_context_error1.phpt similarity index 100% rename from Zend/tests/builtin_in_write_context_error1.phpt rename to Zend/tests/builtin_functions/builtin_in_write_context_error1.phpt diff --git a/Zend/tests/builtin_in_write_context_error2.phpt b/Zend/tests/builtin_functions/builtin_in_write_context_error2.phpt similarity index 100% rename from Zend/tests/builtin_in_write_context_error2.phpt rename to Zend/tests/builtin_functions/builtin_in_write_context_error2.phpt From acd342d82dfaa6ebf65d073f23611c5656871016 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 6 Aug 2026 18:25:54 +0100 Subject: [PATCH 14/25] Zend: deprecate passing a 3rd argument to define() RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_define_with_case_insensitive_being_specified --- .../tests/builtin_functions/define_arg_3.phpt | 25 +++++++++++++++++++ Zend/zend_builtin_functions.c | 14 ++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/builtin_functions/define_arg_3.phpt diff --git a/Zend/tests/builtin_functions/define_arg_3.phpt b/Zend/tests/builtin_functions/define_arg_3.phpt new file mode 100644 index 000000000000..25d1b9dcf35a --- /dev/null +++ b/Zend/tests/builtin_functions/define_arg_3.phpt @@ -0,0 +1,25 @@ +--TEST-- +define() with 3rd argument +--FILE-- +getMessage(), PHP_EOL; +} + +define('MY_CONSTANT', 5, false); +var_dump(MY_CONSTANT); + +?> +--EXPECTF-- +Deprecated: define(): Argument #3 ($case_insensitive) is ignored and treated as false since declaration of case-insensitive constants is no longer supported, passing the argument explicitly is unnecessary in %s on line %d + +Warning: define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported, this will be an error in PHP 9.0 in %s on line %d +Error: Undefined constant "MY_CONSTANT" + +Deprecated: define(): Argument #3 ($case_insensitive) is ignored and treated as false since declaration of case-insensitive constants is no longer supported, passing the argument explicitly is unnecessary in %s on line %d +int(5) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ed0507e0500e..860413f84111 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -568,13 +568,25 @@ ZEND_FUNCTION(define) Z_PARAM_BOOL(non_cs) ZEND_PARSE_PARAMETERS_END(); + if (ZEND_NUM_ARGS() == 3) { + zend_error(E_DEPRECATED, + "define(): Argument #3 ($case_insensitive) is ignored and treated as false since declaration of case-insensitive constants is no longer supported, passing the argument explicitly is unnecessary" + ); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + if (zend_memnstr(ZSTR_VAL(name), "::", sizeof("::") - 1, ZSTR_VAL(name) + ZSTR_LEN(name))) { zend_argument_value_error(1, "cannot be a class constant"); RETURN_THROWS(); } if (non_cs) { - zend_error(E_WARNING, "define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported"); + zend_error(E_WARNING, "define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported, this will be an error in PHP 9.0"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } if (Z_TYPE_P(val) == IS_ARRAY && Z_REFCOUNTED_P(val)) { From 2c1c61de07953f901d95fd93e3ce79b50032e65c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 9 Aug 2026 21:10:20 +0100 Subject: [PATCH 15/25] spl: deprecate spl_object_hash() RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_spl_object_hash --- Zend/tests/bug60598.phpt | 4 ++-- ext/spl/php_spl.c | 12 +++++++----- ext/spl/php_spl.stub.php | 1 + ext/spl/php_spl_arginfo.h | 16 ++++++++++++++-- .../SplObjectStorage/concurrent_deletion.phpt | 2 +- ext/spl/tests/spl_object_hash_deprecated.phpt | 12 ++++++++++++ 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 ext/spl/tests/spl_object_hash_deprecated.phpt diff --git a/Zend/tests/bug60598.phpt b/Zend/tests/bug60598.phpt index ae5914ed3fe0..729a4cfd7f8b 100644 --- a/Zend/tests/bug60598.phpt +++ b/Zend/tests/bug60598.phpt @@ -11,11 +11,11 @@ class ObjectOne { public function __construct() { global $containers; $this->guid = 1; - $containers[spl_object_hash($this)] = $this; + $containers[spl_object_id($this)] = $this; } public function __destruct() { global $containers; - $containers[spl_object_hash($this)] = NULL; + $containers[spl_object_id($this)] = NULL; } } diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index e80917a77067..36be19ed3996 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -16,11 +16,15 @@ #include #endif +#include "php_spl.h" +#include "zend_attributes.h" +#include "php_spl_arginfo.h" +#include "zend_autoload.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" #include "php.h" #include "php_main.h" #include "ext/standard/info.h" -#include "php_spl.h" -#include "php_spl_arginfo.h" #include "spl_functions.h" #include "spl_array.h" #include "spl_directory.h" @@ -30,9 +34,6 @@ #include "spl_dllist.h" #include "spl_fixedarray.h" #include "spl_heap.h" -#include "zend_autoload.h" -#include "zend_exceptions.h" -#include "zend_interfaces.h" ZEND_TLS zend_string *spl_autoload_extensions; @@ -552,6 +553,7 @@ PHP_MINIT_FUNCTION(spl) PHP_MINIT(spl_fixedarray)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(spl_observer)(INIT_FUNC_ARGS_PASSTHRU); + register_php_spl_symbols(module_number); return SUCCESS; } /* }}} */ diff --git a/ext/spl/php_spl.stub.php b/ext/spl/php_spl.stub.php index d3b5d44f11d1..814a5db9bd9b 100644 --- a/ext/spl/php_spl.stub.php +++ b/ext/spl/php_spl.stub.php @@ -42,6 +42,7 @@ function spl_autoload_unregister(callable $callback): bool {} function spl_classes(): array {} /** @refcount 1 */ +#[\Deprecated(message: "consider using spl_object_id() instead", since: "8.6")] function spl_object_hash(object $object): string {} function spl_object_id(object $object): int {} diff --git a/ext/spl/php_spl_arginfo.h b/ext/spl/php_spl_arginfo.h index 8b0ea4b7245b..e9e34434479c 100644 --- a/ext/spl/php_spl_arginfo.h +++ b/ext/spl/php_spl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_spl.stub.php instead. - * Stub hash: 21ec2dcca99c85c90afcd319da76016a9f678dc2 */ + * Stub hash: 3b8b5f35858786e5cf82fd59048d3ed489c2c559 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_implements, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_INFO(0, object_or_class) @@ -88,10 +88,22 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(spl_autoload_register, arginfo_spl_autoload_register) ZEND_FE(spl_autoload_unregister, arginfo_spl_autoload_unregister) ZEND_FE(spl_classes, arginfo_spl_classes) - ZEND_FE(spl_object_hash, arginfo_spl_object_hash) + ZEND_RAW_FENTRY("spl_object_hash", zif_spl_object_hash, arginfo_spl_object_hash, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(spl_object_id, arginfo_spl_object_id) ZEND_FE(iterator_apply, arginfo_iterator_apply) ZEND_FE(iterator_count, arginfo_iterator_count) ZEND_FE(iterator_to_array, arginfo_iterator_to_array) ZEND_FE_END }; + +static void register_php_spl_symbols(int module_number) +{ + + zend_attribute *attribute_Deprecated_func_spl_object_hash_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "spl_object_hash", sizeof("spl_object_hash") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_spl_object_hash_0_arg0_str = zend_string_init("consider using spl_object_id() instead", strlen("consider using spl_object_id() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_spl_object_hash_0->args[0].value, attribute_Deprecated_func_spl_object_hash_0_arg0_str); + attribute_Deprecated_func_spl_object_hash_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_string *attribute_Deprecated_func_spl_object_hash_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_spl_object_hash_0->args[1].value, attribute_Deprecated_func_spl_object_hash_0_arg1_str); + attribute_Deprecated_func_spl_object_hash_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); +} diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt index a4b4e7d3a986..285945616e95 100644 --- a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt @@ -12,7 +12,7 @@ class EvilStorage extends SplObjectStorage { if ($this->mutate) { $victim[new stdClass()] = null; } - return spl_object_hash($obj); + return spl_object_id($obj); } } diff --git a/ext/spl/tests/spl_object_hash_deprecated.phpt b/ext/spl/tests/spl_object_hash_deprecated.phpt new file mode 100644 index 000000000000..a2aae7fa869b --- /dev/null +++ b/ext/spl/tests/spl_object_hash_deprecated.phpt @@ -0,0 +1,12 @@ +--TEST-- +spl_object_hash(): is deprecated +--FILE-- + +--EXPECTF-- +Deprecated: Function spl_object_hash() is deprecated since 8.6, consider using spl_object_id() instead in %s on line %d +string(32) "00000000000000010000000000000000" From 6214a2165936af4c9d03f3ff083d0a2afd67a4d3 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 9 Aug 2026 21:12:20 +0100 Subject: [PATCH 16/25] spl: deprecate spl_classes() RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_spl_classes --- ext/spl/php_spl.stub.php | 1 + ext/spl/php_spl_arginfo.h | 15 +++++++++++---- ext/spl/tests/spl_classes.phpt | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ext/spl/php_spl.stub.php b/ext/spl/php_spl.stub.php index 814a5db9bd9b..2c84161e43af 100644 --- a/ext/spl/php_spl.stub.php +++ b/ext/spl/php_spl.stub.php @@ -39,6 +39,7 @@ function spl_autoload_unregister(callable $callback): bool {} * @return array * @refcount 1 */ +#[\Deprecated(message: "use ReflectionExtension::getClassNames() instead", since: "8.6")] function spl_classes(): array {} /** @refcount 1 */ diff --git a/ext/spl/php_spl_arginfo.h b/ext/spl/php_spl_arginfo.h index e9e34434479c..fc3f4c08022d 100644 --- a/ext/spl/php_spl_arginfo.h +++ b/ext/spl/php_spl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_spl.stub.php instead. - * Stub hash: 3b8b5f35858786e5cf82fd59048d3ed489c2c559 */ + * Stub hash: 5f9f72a101d08dc67472461115b90534d4805ddc */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_implements, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_INFO(0, object_or_class) @@ -87,7 +87,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(spl_autoload_functions, arginfo_spl_autoload_functions) ZEND_FE(spl_autoload_register, arginfo_spl_autoload_register) ZEND_FE(spl_autoload_unregister, arginfo_spl_autoload_unregister) - ZEND_FE(spl_classes, arginfo_spl_classes) + ZEND_RAW_FENTRY("spl_classes", zif_spl_classes, arginfo_spl_classes, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("spl_object_hash", zif_spl_object_hash, arginfo_spl_object_hash, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(spl_object_id, arginfo_spl_object_id) ZEND_FE(iterator_apply, arginfo_iterator_apply) @@ -99,11 +99,18 @@ static const zend_function_entry ext_functions[] = { static void register_php_spl_symbols(int module_number) { + zend_attribute *attribute_Deprecated_func_spl_classes_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "spl_classes", sizeof("spl_classes") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_spl_classes_0_arg0_str = zend_string_init("use ReflectionExtension::getClassNames() instead", strlen("use ReflectionExtension::getClassNames() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_spl_classes_0->args[0].value, attribute_Deprecated_func_spl_classes_0_arg0_str); + attribute_Deprecated_func_spl_classes_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_string *attribute_Deprecated_func_spl_classes_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_spl_classes_0->args[1].value, attribute_Deprecated_func_spl_classes_0_arg1_str); + attribute_Deprecated_func_spl_classes_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_attribute *attribute_Deprecated_func_spl_object_hash_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "spl_object_hash", sizeof("spl_object_hash") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_func_spl_object_hash_0_arg0_str = zend_string_init("consider using spl_object_id() instead", strlen("consider using spl_object_id() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_spl_object_hash_0->args[0].value, attribute_Deprecated_func_spl_object_hash_0_arg0_str); attribute_Deprecated_func_spl_object_hash_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - zend_string *attribute_Deprecated_func_spl_object_hash_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); - ZVAL_STR(&attribute_Deprecated_func_spl_object_hash_0->args[1].value, attribute_Deprecated_func_spl_object_hash_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_spl_object_hash_0->args[1].value, attribute_Deprecated_func_spl_classes_0_arg1_str); attribute_Deprecated_func_spl_object_hash_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); } diff --git a/ext/spl/tests/spl_classes.phpt b/ext/spl/tests/spl_classes.phpt index a47c86eff837..6630201eee3c 100644 --- a/ext/spl/tests/spl_classes.phpt +++ b/ext/spl/tests/spl_classes.phpt @@ -8,5 +8,6 @@ Testfest 2009 Munich ---EXPECT-- +--EXPECTF-- +Deprecated: Function spl_classes() is deprecated since 8.6, use ReflectionExtension::getClassNames() instead in %s on line %d bool(true) From e95647ce3619d13b7f59b792460a7d4d11be49d3 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 9 Aug 2026 21:34:44 +0100 Subject: [PATCH 17/25] spl: deprecate ArrayIterator methods that make little sense RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_arrayiterator_methods_that_inherit_arrayobject_implementation --- ext/spl/spl_array.c | 1 + ext/spl/spl_array.stub.php | 10 +++ ext/spl/spl_array_arginfo.h | 64 +++++++++++++++---- .../arrayIterator_ksort_basic1.phpt | 3 +- .../arrayObject_getFlags_basic2.phpt | 4 ++ ext/spl/tests/ArrayObject/array_017.phpt | 64 +++++++++++++------ ext/spl/tests/{ => ArrayObject}/bug67539.phpt | 7 +- ext/spl/tests/bug46115.phpt | 4 +- 8 files changed, 122 insertions(+), 35 deletions(-) rename ext/spl/tests/{ => ArrayObject}/bug67539.phpt (62%) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index af603f3abf6b..257a7077a208 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -18,6 +18,7 @@ #include "php.h" #include "ext/standard/php_var.h" +#include "zend_attributes.h" #include "zend_smart_str.h" #include "zend_interfaces.h" #include "zend_exceptions.h" diff --git a/ext/spl/spl_array.stub.php b/ext/spl/spl_array.stub.php index 1f4c81057dcb..bc21917418c7 100644 --- a/ext/spl/spl_array.stub.php +++ b/ext/spl/spl_array.stub.php @@ -139,60 +139,70 @@ public function count(): int {} * @tentative-return-type * @implementation-alias ArrayObject::getFlags */ + #[\Deprecated(since: "8.6")] public function getFlags(): int {} /** * @tentative-return-type * @implementation-alias ArrayObject::setFlags */ + #[\Deprecated(since: "8.6")] public function setFlags(int $flags): void {} /** * @tentative-return-type * @implementation-alias ArrayObject::asort */ + #[\Deprecated(since: "8.6")] public function asort(int $flags = SORT_REGULAR): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::ksort */ + #[\Deprecated(since: "8.6")] public function ksort(int $flags = SORT_REGULAR): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::uasort */ + #[\Deprecated(since: "8.6")] public function uasort(callable $callback): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::uksort */ + #[\Deprecated(since: "8.6")] public function uksort(callable $callback): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::natsort */ + #[\Deprecated(since: "8.6")] public function natsort(): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::natcasesort */ + #[\Deprecated(since: "8.6")] public function natcasesort(): true {} /** * @tentative-return-type * @implementation-alias ArrayObject::unserialize */ + #[\Deprecated(since: "8.6")] public function unserialize(string $data): void {} /** * @tentative-return-type * @implementation-alias ArrayObject::serialize */ + #[\Deprecated(since: "8.6")] public function serialize(): string {} /** diff --git a/ext/spl/spl_array_arginfo.h b/ext/spl/spl_array_arginfo.h index fbe290693640..0677200b0b0a 100644 --- a/ext/spl/spl_array_arginfo.h +++ b/ext/spl/spl_array_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit spl_array.stub.php instead. - * Stub hash: c52e89992bd3c04877daab47f4328af0b6ce619e */ + * Stub hash: c50ad88a1603d7805b7b77b60bd9c9bf0aa0a008 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ArrayObject___construct, 0, 0, 0) ZEND_ARG_TYPE_MASK(0, array, MAY_BE_ARRAY|MAY_BE_OBJECT, "[]") @@ -226,16 +226,16 @@ static const zend_function_entry class_ArrayIterator_methods[] = { ZEND_RAW_FENTRY("append", zim_ArrayObject_append, arginfo_class_ArrayIterator_append, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getArrayCopy", zim_ArrayObject_getArrayCopy, arginfo_class_ArrayIterator_getArrayCopy, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("count", zim_ArrayObject_count, arginfo_class_ArrayIterator_count, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("getFlags", zim_ArrayObject_getFlags, arginfo_class_ArrayIterator_getFlags, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("setFlags", zim_ArrayObject_setFlags, arginfo_class_ArrayIterator_setFlags, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("asort", zim_ArrayObject_asort, arginfo_class_ArrayIterator_asort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("ksort", zim_ArrayObject_ksort, arginfo_class_ArrayIterator_ksort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("uasort", zim_ArrayObject_uasort, arginfo_class_ArrayIterator_uasort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("uksort", zim_ArrayObject_uksort, arginfo_class_ArrayIterator_uksort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("natsort", zim_ArrayObject_natsort, arginfo_class_ArrayIterator_natsort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("natcasesort", zim_ArrayObject_natcasesort, arginfo_class_ArrayIterator_natcasesort, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("unserialize", zim_ArrayObject_unserialize, arginfo_class_ArrayIterator_unserialize, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("serialize", zim_ArrayObject_serialize, arginfo_class_ArrayIterator_serialize, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_RAW_FENTRY("getFlags", zim_ArrayObject_getFlags, arginfo_class_ArrayIterator_getFlags, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("setFlags", zim_ArrayObject_setFlags, arginfo_class_ArrayIterator_setFlags, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("asort", zim_ArrayObject_asort, arginfo_class_ArrayIterator_asort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("ksort", zim_ArrayObject_ksort, arginfo_class_ArrayIterator_ksort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("uasort", zim_ArrayObject_uasort, arginfo_class_ArrayIterator_uasort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("uksort", zim_ArrayObject_uksort, arginfo_class_ArrayIterator_uksort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("natsort", zim_ArrayObject_natsort, arginfo_class_ArrayIterator_natsort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("natcasesort", zim_ArrayObject_natcasesort, arginfo_class_ArrayIterator_natcasesort, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("unserialize", zim_ArrayObject_unserialize, arginfo_class_ArrayIterator_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("serialize", zim_ArrayObject_serialize, arginfo_class_ArrayIterator_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY("__serialize", zim_ArrayObject___serialize, arginfo_class_ArrayIterator___serialize, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("__unserialize", zim_ArrayObject___unserialize, arginfo_class_ArrayIterator___unserialize, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(ArrayIterator, rewind, arginfo_class_ArrayIterator_rewind, ZEND_ACC_PUBLIC) @@ -297,6 +297,48 @@ static zend_class_entry *register_class_ArrayIterator(zend_class_entry *class_en zend_declare_typed_class_constant(class_entry, const_ARRAY_AS_PROPS_name, &const_ARRAY_AS_PROPS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release_ex(const_ARRAY_AS_PROPS_name, true); + + zend_attribute *attribute_Deprecated_func_getflags_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "getflags", sizeof("getflags") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + zend_string *attribute_Deprecated_func_getflags_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_getflags_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_getflags_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_setflags_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setflags", sizeof("setflags") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_setflags_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_setflags_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_asort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "asort", sizeof("asort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_asort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_asort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_ksort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "ksort", sizeof("ksort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_ksort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_ksort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_uasort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "uasort", sizeof("uasort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_uasort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_uasort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_uksort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "uksort", sizeof("uksort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_uksort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_uksort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_natsort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "natsort", sizeof("natsort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_natsort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_natsort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_natcasesort_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "natcasesort", sizeof("natcasesort") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_natcasesort_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_natcasesort_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_unserialize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "unserialize", sizeof("unserialize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_unserialize_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_unserialize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_serialize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "serialize", sizeof("serialize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + ZVAL_STR_COPY(&attribute_Deprecated_func_serialize_0->args[0].value, attribute_Deprecated_func_getflags_0_arg0_str); + attribute_Deprecated_func_serialize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + return class_entry; } diff --git a/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt index 642827a28f8b..ad87c58f9dd9 100644 --- a/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt +++ b/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt @@ -9,7 +9,8 @@ var_dump($arrIter->ksort()); var_dump($arrIter); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method ArrayIterator::ksort() is deprecated since 8.6 in %s on line %d bool(true) object(ArrayIterator)#1 (1) { ["storage":"ArrayIterator":private]=> diff --git a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt index 0d0111edd1ec..6b5977fa3a81 100644 --- a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt @@ -21,9 +21,13 @@ int(3) Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d int(3) + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d int(3) Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d int(3) Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d diff --git a/ext/spl/tests/ArrayObject/array_017.phpt b/ext/spl/tests/ArrayObject/array_017.phpt index 2a80386b6f73..2ac5ce816ed1 100644 --- a/ext/spl/tests/ArrayObject/array_017.phpt +++ b/ext/spl/tests/ArrayObject/array_017.phpt @@ -152,7 +152,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -180,6 +180,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(0) @@ -197,7 +199,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#2 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -209,7 +211,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -250,6 +252,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(0) @@ -267,7 +271,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#3 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -279,7 +283,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -323,6 +327,8 @@ bool(true) int(1) bool(false) ArrayIteratorEx::setFlags(2) + +Deprecated: Method ArrayIterator::setFlags() is deprecated since 8.6 in %s on line %d int(1) bool(true) ===CHECK=== @@ -345,7 +351,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -373,6 +379,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(1) @@ -390,7 +398,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#3 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -402,7 +410,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -443,6 +451,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(1) @@ -460,7 +470,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#2 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -472,7 +482,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (6) { + object(ArrayObjectEx)#1 (6) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -516,6 +526,8 @@ bool(true) int(1) bool(false) ArrayIteratorEx::setFlags(3) + +Deprecated: Method ArrayIterator::setFlags() is deprecated since 8.6 in %s on line %d int(1) bool(true) #####EXCHANGE##### @@ -542,7 +554,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -561,6 +573,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(0) @@ -578,7 +592,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#2 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -590,7 +604,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -622,6 +636,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(0) @@ -639,7 +655,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#3 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -651,7 +667,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -686,6 +702,8 @@ bool(false) int(1) bool(false) ArrayIteratorEx::setFlags(2) + +Deprecated: Method ArrayIterator::setFlags() is deprecated since 8.6 in %s on line %d int(1) bool(true) ===CHECK=== @@ -708,7 +726,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -727,6 +745,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(1) @@ -744,7 +764,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#3 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -756,7 +776,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -788,6 +808,8 @@ ArrayIteratorEx::__construct() Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() + +Deprecated: Method ArrayIterator::getFlags() is deprecated since 8.6 in %s on line %d array(3) { ["Flags"]=> int(1) @@ -805,7 +827,7 @@ array(3) { int(5) } ["$this"]=> - object(ArrayIteratorEx)#%d (6) { + object(ArrayIteratorEx)#2 (6) { ["pub2"]=> int(1) ["pro2":protected]=> @@ -817,7 +839,7 @@ array(3) { ["dyn2"]=> int(5) ["storage":"ArrayIterator":private]=> - object(ArrayObjectEx)#%d (5) { + object(ArrayObjectEx)#1 (5) { ["pub1"]=> int(1) ["pro1":protected]=> @@ -852,5 +874,7 @@ bool(false) int(1) bool(false) ArrayIteratorEx::setFlags(3) + +Deprecated: Method ArrayIterator::setFlags() is deprecated since 8.6 in %s on line %d int(1) bool(true) diff --git a/ext/spl/tests/bug67539.phpt b/ext/spl/tests/ArrayObject/bug67539.phpt similarity index 62% rename from ext/spl/tests/bug67539.phpt rename to ext/spl/tests/ArrayObject/bug67539.phpt index 7149bd55a42f..694cc85f365d 100644 --- a/ext/spl/tests/bug67539.phpt +++ b/ext/spl/tests/ArrayObject/bug67539.phpt @@ -16,5 +16,10 @@ function badsort($a, $b) { $it->uksort('badsort'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method ArrayIterator::uksort() is deprecated since 8.6 in %s on line %d + +Deprecated: Method ArrayIterator::serialize() is deprecated since 8.6 in %s on line %d + +Deprecated: Method ArrayIterator::unserialize() is deprecated since 8.6 in %s on line %d Error: Modification of ArrayObject during sorting is prohibited diff --git a/ext/spl/tests/bug46115.phpt b/ext/spl/tests/bug46115.phpt index 71207d8a25ee..3b2f9d1dfef3 100644 --- a/ext/spl/tests/bug46115.phpt +++ b/ext/spl/tests/bug46115.phpt @@ -3,9 +3,9 @@ Bug #46115 (Memory leak when calling a method using Reflection) --FILE-- invoke($h); ?> DONE ---EXPECT-- +--EXPECTF-- DONE From bad89ea44532fcaa7b8ee02b09c5b35cd14525e0 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 10 Aug 2026 18:34:18 +0100 Subject: [PATCH 18/25] Zend: remove zend_parse_parameter() (#23051) This API is far worse than just using the existing zend_parse_arg_TYPE() APIs. A SourceGraph search [1] shows this API is effectively only used by ext/ds to which a PR migrating away from this API has been submitted. [2] The other two usages are from a now deprecated extension [3] and @arnauld-lb's now longer maintained php-go project. [4] As such we think it is reasonable to remove said API. [1] https://sourcegraph.com/search?q=context:global+-f:zend_API.c+-f:zend_API.h+zend_parse_parameter%28&patternType=keyword&sm=0 [2] https://github.com/php-ds/ext-ds/pull/232 [3] https://github.com/libvips/php-vips-ext [4] https://github.com/arnaud-lb/php-go --- Zend/zend_API.c | 12 ------------ Zend/zend_API.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 7d407f7e9053..d7ed141a3e1d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1129,18 +1129,6 @@ static zend_result zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, cons } /* }}} */ -ZEND_API zend_result zend_parse_parameter(int flags, uint32_t arg_num, zval *arg, const char *spec, ...) -{ - va_list va; - zend_result ret; - - va_start(va, spec); - ret = zend_parse_arg(arg_num, arg, &va, &spec, flags); - va_end(va); - - return ret; -} - static ZEND_COLD void zend_parse_parameters_debug_error(const char *msg) { const zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope diff --git a/Zend/zend_API.h b/Zend/zend_API.h index aff9846d21b8..ad224884f360 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -373,8 +373,6 @@ ZEND_API zend_string *zend_zval_get_legacy_type(const zval *arg); ZEND_API zend_result zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec, ...); ZEND_API zend_result zend_parse_method_parameters_ex(int flags, uint32_t num_args, zval *this_ptr, const char *type_spec, ...); -ZEND_API zend_result zend_parse_parameter(int flags, uint32_t arg_num, zval *arg, const char *spec, ...); - /* End of parameter parsing API -- andrei */ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type); From 34f5a729d3acffec08160f59a155c2c638d5cfe2 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 10 Aug 2026 18:57:44 +0100 Subject: [PATCH 19/25] Amend UPGRADING for recent deprecations and engine API changes --- UPGRADING | 59 +++++++++++++++++++++++++++++++++++++++++++++ UPGRADING.INTERNALS | 2 ++ 2 files changed, 61 insertions(+) diff --git a/UPGRADING b/UPGRADING index e4669740b35f..ad7f51bdeb24 100644 --- a/UPGRADING +++ b/UPGRADING @@ -447,6 +447,15 @@ PHP 8.6 UPGRADE NOTES RFC: https://wiki.php.net/rfc/deprecate-return-value-from-construct . Making __construct() and __destruct() a Generator is now deprecated. RFC: https://wiki.php.net/rfc/deprecate-return-value-from-construct + . Naming a function readonly is now deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_the_possibility_to_name_a_function_readonly + . Passing a 3rd argument to define() is now deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_define_with_case_insensitive_being_specified + +- BZ2 + . Passing an object for the Bzip2 {de}compression stream filter is now + deprecated. Use get_object_vars() on the object instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_as_parameters_to_the_bzip2decompress_and_bzip2compress_stream_filters - GMP . The shift (<<, >>) and exponentiation (**) operators on GMP objects now @@ -457,12 +466,62 @@ PHP 8.6 UPGRADE NOTES . Mbregex has been deprecated, because the underlying Oniguruma library is no longer maintained. RFC: https://wiki.php.net/rfc/eol-oniguruma + . Passing objects to mb_convert_variables() is now deprecated + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_vars_parameter_of_mb_convert_variables + +- SPL: + . The spl_classes() function is now deprecated, use + ReflectionExtension::getClassNames() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_spl_classes + . The spl_object_hash() function is now deprecated, use spl_object_id() + instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_spl_object_hash + . The following ArrayIterator methods are now deprecated: + * ArrayIterator::getFlags() + * ArrayIterator::setFlags() + * ArrayIterator::asort() + * ArrayIterator::ksort() + * ArrayIterator::uasort() + * ArrayIterator::uksort() + * ArrayIterator::natsort() + * ArrayIterator::natcasesort() + * ArrayIterator::unserialize() + * ArrayIterator::serialize() + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_arrayiterator_methods_that_inherit_arrayobject_implementation - Standard: . Using more than 16 filters in a php://filter URL without configuring the "filter.max_filter_count" stream context option now emits an E_DEPRECATED warning. Use stream_filter_append() or configure this option explicitly. RFC: https://wiki.php.net/rfc/limit-maximum-number-of-filter-chains + . Passing an object to array_walk{_recursive} is now deprecated. Use + get_object_vars() on the object instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_array_parameter_of_array_walk_and_array_walk_recursive + . The is_double() function is now deprecated, use is_float() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_double + . The is_long() and is_integer() functions are now deprecated, use is_int() + instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_integer + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_long + . The doubleval() function is now deprecated, use floatval() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_doubleval + . The strcoll() function is now deprecated, use Collator::compare() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_strcoll + . The SORT_LOCALE_STRING constant for the family of sort functions is now + deprecated, use one of the following functions instead: + * Collator::sort() + * Collator::asort() + * Collator::sort() + * Collator::sortWithSortKeys() + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_sort_locale_string_flag_for_sort_functions + +- Zlib + . Passing an object for the zlib deflate and inflate stream filter is now + deprecated. Use get_object_vars() on the object instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_as_parameters_to_the_zlibinflate_and_zlibdeflate_stream_filters + . Passing an object to the $option argument to deflate_init and inflate_init + is now deprecated. Use get_object_vars() on the object instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_options_parameter_of_deflate_init_and_inflate_init ======================================== 5. Changed Functions diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 3c0d3b4f80fa..4be8421dd7b1 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -134,6 +134,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES . The PHP stream function _php_stream_flush() was removed, instead the PHP macro php_stream_flush() is now a proper function. . The zend_save_error_handling() function was removed. + . The zend_parse_parameter() function has been removed, use one fo the + zend_parse_arg_TYPE() APIs instead. - Changed: . Internal functions that return by reference are now expected to From 1cf82bef0a7e3c85b40eff2539ab6c9878dcd872 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 15 Jul 2026 12:53:27 +0100 Subject: [PATCH 20/25] zlib: Add test with invalid levels --- ext/zlib/tests/zlib_wrapper_level_errors.phpt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 ext/zlib/tests/zlib_wrapper_level_errors.phpt diff --git a/ext/zlib/tests/zlib_wrapper_level_errors.phpt b/ext/zlib/tests/zlib_wrapper_level_errors.phpt new file mode 100644 index 000000000000..cc586da568b1 --- /dev/null +++ b/ext/zlib/tests/zlib_wrapper_level_errors.phpt @@ -0,0 +1,45 @@ +--TEST-- +compress.zlib:// wrapper with invalid compression level +--EXTENSIONS-- +zlib +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +int(%d) + +Warning: Object of class stdClass could not be converted to int in %s on line %d +int(%d) +int(0) From 148afdb60aaa9ab8696746c59c7b9ed00fbf3274 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 15 Jul 2026 12:53:39 +0100 Subject: [PATCH 21/25] zlib: use new stream error API --- ext/zlib/tests/zlib_wrapper_level_errors.phpt | 3 +- ext/zlib/zlib_fopen_wrapper.c | 42 ++++++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/ext/zlib/tests/zlib_wrapper_level_errors.phpt b/ext/zlib/tests/zlib_wrapper_level_errors.phpt index cc586da568b1..cdc4fff502e3 100644 --- a/ext/zlib/tests/zlib_wrapper_level_errors.phpt +++ b/ext/zlib/tests/zlib_wrapper_level_errors.phpt @@ -38,8 +38,9 @@ var_dump($size_oob); ?> --EXPECTF-- +Warning: fopen(): zlib "level" context option must be of type int, string given in %s on line %d int(%d) -Warning: Object of class stdClass could not be converted to int in %s on line %d +Warning: fopen(): zlib "level" context option must be of type int, stdClass given in %s on line %d int(%d) int(0) diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c index aebf368a16ed..2b922bf1d11e 100644 --- a/ext/zlib/zlib_fopen_wrapper.c +++ b/ext/zlib/zlib_fopen_wrapper.c @@ -31,11 +31,13 @@ struct php_gz_stream_data_t { static void php_gziop_report_errors(php_stream *stream, size_t count, const char *verb) { if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { - struct php_gz_stream_data_t *self = stream->abstract; + const struct php_gz_stream_data_t *self = stream->abstract; int error = 0; gzerror(self->gz_file, &error); if (error == Z_ERRNO) { - php_error_docref(NULL, E_NOTICE, "%s of %zu bytes failed with errno=%d %s", verb, count, errno, strerror(errno)); + php_stream_notice(stream, ReadFailed, + "%s of %zu bytes failed with errno=%d %s", + verb, count, errno, strerror(errno)); } } } @@ -98,12 +100,13 @@ static ssize_t php_gziop_write(php_stream *stream, const char *buf, size_t count static int php_gziop_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { - struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract; + const struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract; - assert(self != NULL); + ZEND_ASSERT(self != NULL); if (whence == SEEK_END) { - php_error_docref(NULL, E_WARNING, "SEEK_END is not supported"); + php_stream_wrapper_warn(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + SeekNotSupported, "SEEK_END is not supported"); return -1; } @@ -171,14 +174,12 @@ const php_stream_ops php_stream_gzio_ops = { php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { - struct php_gz_stream_data_t *self; php_stream *stream = NULL, *innerstream = NULL; /* sanity check the stream: it can be either read-only or write-only */ if (strchr(mode, '+')) { - if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Cannot open a zlib stream for reading and writing at the same time!"); - } + php_stream_wrapper_log_warn(wrapper, context, REPORT_ERRORS, ModeNotSupported, + "Cannot open a zlib stream for reading and writing at the same time!"); return NULL; } @@ -194,14 +195,23 @@ php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, const char *path, con php_socket_t fd; if (SUCCESS == php_stream_cast(innerstream, PHP_STREAM_AS_FD, (void **) &fd, REPORT_ERRORS)) { - self = emalloc(sizeof(*self)); + struct php_gz_stream_data_t *self = emalloc(sizeof(*self)); self->stream = innerstream; self->gz_file = gzdopen(dup(fd), mode); if (self->gz_file) { - zval *zlevel = context ? php_stream_context_get_option(context, "zlib", "level") : NULL; - if (zlevel && (Z_OK != gzsetparams(self->gz_file, zval_get_long(zlevel), Z_DEFAULT_STRATEGY))) { - php_error(E_WARNING, "failed setting compression level"); + const zval *zlevel = context ? php_stream_context_get_option(context, "zlib", "level") : NULL; + + if (zlevel) { + bool failed = true; + const zend_long level = zval_try_get_long(zlevel, &failed); + if (UNEXPECTED(failed)) { + php_stream_wrapper_log_warn(wrapper, context, REPORT_ERRORS, InvalidParam, + "zlib \"level\" context option must be of type int, %s given", zend_zval_type_name(zlevel)); + } else if (Z_OK != gzsetparams(self->gz_file, level, Z_DEFAULT_STRATEGY)) { + php_stream_wrapper_log_warn(wrapper, context, REPORT_ERRORS, Generic, + "failed setting compression level"); + } } stream = php_stream_alloc_rel(&php_stream_gzio_ops, self, 0, mode); @@ -214,9 +224,9 @@ php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, const char *path, con } efree(self); - if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "gzopen failed"); - } + + php_stream_wrapper_log_warn(wrapper, context, options, OpenFailed, + "gzopen failed"); } php_stream_close(innerstream); From 4b26ff1698b96e00682a2afd063ff01dc915d478 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 11 Aug 2026 03:02:18 +0800 Subject: [PATCH 22/25] RFC: Deprecate metaphone() (#21889) This implement RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_metaphone_function which deprecate the metaphone function. --- NEWS | 1 + UPGRADING | 3 +++ ext/standard/basic_functions.stub.php | 1 + ext/standard/basic_functions_arginfo.h | 25 ++++++++++++------- ext/standard/basic_functions_decl.h | 8 +++--- ext/standard/tests/GHSA-96wq-48vp-hh57.phpt | 3 ++- ext/standard/tests/strings/bug44242.phpt | 7 +++++- ext/standard/tests/strings/bug47443.phpt | 7 +++++- ext/standard/tests/strings/bug48709.phpt | 17 ++++++++++++- ext/standard/tests/strings/metaphone.phpt | 19 +++++++++++++- .../tests/strings/metaphone_deprecation.phpt | 11 ++++++++ 11 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 ext/standard/tests/strings/metaphone_deprecation.phpt diff --git a/NEWS b/NEWS index 2d6cde54b325..7bbc50fcccfe 100644 --- a/NEWS +++ b/NEWS @@ -94,6 +94,7 @@ PHP NEWS . Added the "filter.max_filter_count" stream context option for php://filter URLs. Using more than 16 filters without configuring this option is now deprecated. (Sjoerd Langkemper) + . metaphone() is now deprecated. (Weilin Du) . Improved performance of array_intersect(). (mehmetcansahin) . Fixed bug GH-23006 (phpcredits() full-page HTML title says phpinfo()). (Weilin Du) diff --git a/UPGRADING b/UPGRADING index ad7f51bdeb24..754157e75b22 100644 --- a/UPGRADING +++ b/UPGRADING @@ -490,6 +490,9 @@ PHP 8.6 UPGRADE NOTES RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_arrayiterator_methods_that_inherit_arrayobject_implementation - Standard: + . metaphone() is deprecated. + Please use a userland phonetic matching library instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_metaphone_function . Using more than 16 filters in a php://filter URL without configuring the "filter.max_filter_count" stream context option now emits an E_DEPRECATED warning. Use stream_filter_append() or configure this option explicitly. diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index fb7c5b90fdb8..9f52df10e1d3 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2239,6 +2239,7 @@ function inet_pton(string $ip): string|false {} /* metaphone.c */ /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: 'use a userland phonetic matching library instead')] function metaphone(string $string, int $max_phonemes = 0): string {} /* {{{ head.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index c352ef20a40a..4f0434b9d8a3 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8 + * Stub hash: 8f5682d85611126ee12182af46cb2905a0bd0e57 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -3136,7 +3136,7 @@ static const zend_function_entry ext_functions[] = { #endif ZEND_FE(inet_ntop, arginfo_inet_ntop) ZEND_FE(inet_pton, arginfo_inet_pton) - ZEND_FE(metaphone, arginfo_metaphone) + ZEND_RAW_FENTRY("metaphone", zif_metaphone, arginfo_metaphone, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(header, arginfo_header) ZEND_FE(header_remove, arginfo_header_remove) ZEND_FE(setrawcookie, arginfo_setrawcookie) @@ -3944,6 +3944,14 @@ static void register_basic_functions_symbols(int module_number) attribute_Deprecated_func_strptime_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); #endif + zend_attribute *attribute_Deprecated_func_metaphone_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "metaphone", sizeof("metaphone") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_metaphone_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_metaphone_0->args[0].value, attribute_Deprecated_func_metaphone_0_arg0_str); + attribute_Deprecated_func_metaphone_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_metaphone_0_arg1_str = zend_string_init("use a userland phonetic matching library instead", strlen("use a userland phonetic matching library instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_metaphone_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg1_str); + attribute_Deprecated_func_metaphone_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_func_assert_options_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "assert_options", sizeof("assert_options") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); ZVAL_STR(&attribute_Deprecated_func_assert_options_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_func_assert_options_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); @@ -3952,8 +3960,7 @@ static void register_basic_functions_symbols(int module_number) zend_string *attribute_Deprecated_func_strcoll_0_arg0_str = zend_string_init("use Collator::compare() instead", strlen("use Collator::compare() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_strcoll_0->args[0].value, attribute_Deprecated_func_strcoll_0_arg0_str); attribute_Deprecated_func_strcoll_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - zend_string *attribute_Deprecated_func_strcoll_0_arg1_str = zend_string_init("8.6", strlen("8.6"), 1); - ZVAL_STR(&attribute_Deprecated_func_strcoll_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_strcoll_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_func_strcoll_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_utf8_encode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_encode", sizeof("utf8_encode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); @@ -3986,34 +3993,34 @@ static void register_basic_functions_symbols(int module_number) zend_string *attribute_Deprecated_func_doubleval_0_arg0_str = zend_string_init("use floatval() instead", strlen("use floatval() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_doubleval_0->args[0].value, attribute_Deprecated_func_doubleval_0_arg0_str); attribute_Deprecated_func_doubleval_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_doubleval_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_doubleval_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_func_doubleval_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_integer_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_integer", sizeof("is_integer") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_func_is_integer_0_arg0_str = zend_string_init("use is_int() instead", strlen("use is_int() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_is_integer_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); attribute_Deprecated_func_is_integer_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_integer_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_integer_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_func_is_integer_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_long_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_long", sizeof("is_long") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[0].value, attribute_Deprecated_func_is_integer_0_arg0_str); attribute_Deprecated_func_is_long_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_long_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_func_is_long_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_is_double_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "is_double", sizeof("is_double") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_func_is_double_0_arg0_str = zend_string_init("use is_float() instead", strlen("use is_float() instead"), 1); ZVAL_STR(&attribute_Deprecated_func_is_double_0->args[0].value, attribute_Deprecated_func_is_double_0_arg0_str); attribute_Deprecated_func_is_double_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_func_is_double_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_func_is_double_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_func_is_double_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_const_SORT_LOCALE_STRING_0 = zend_add_global_constant_attribute(const_SORT_LOCALE_STRING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); zend_string *attribute_Deprecated_const_SORT_LOCALE_STRING_0_arg0_str = zend_string_init("use one of the Collator::*sort*() methods instead", strlen("use one of the Collator::*sort*() methods instead"), 1); ZVAL_STR(&attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[0].value, attribute_Deprecated_const_SORT_LOCALE_STRING_0_arg0_str); attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - ZVAL_STR_COPY(&attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[1].value, attribute_Deprecated_func_strcoll_0_arg1_str); + ZVAL_STR_COPY(&attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[1].value, attribute_Deprecated_func_metaphone_0_arg0_str); attribute_Deprecated_const_SORT_LOCALE_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index 159d30b2c002..40e4c918ba60 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8 */ + * Stub hash: 8f5682d85611126ee12182af46cb2905a0bd0e57 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H -#define ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H +#define ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H typedef enum zend_enum_SortDirection { ZEND_ENUM_SortDirection_Ascending = 1, @@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_21b2089bd39aadeeb8730e4bb2fecbb32e65d1c8_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H */ diff --git a/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt index f8a01f48a115..d9aa9af6a474 100644 --- a/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt +++ b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt @@ -18,5 +18,6 @@ metaphone($str, 1); ?> ===DONE=== ---EXPECT-- +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d ===DONE=== diff --git a/ext/standard/tests/strings/bug44242.phpt b/ext/standard/tests/strings/bug44242.phpt index 00adda2be670..78e371abaad6 100644 --- a/ext/standard/tests/strings/bug44242.phpt +++ b/ext/standard/tests/strings/bug44242.phpt @@ -8,7 +8,12 @@ echo metaphone('CMXFXV'), "\n"; echo metaphone('CMXFXZXZ'), "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d KMKSFKSS + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d KMKSFKSF + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d KMKSFKSSKSS diff --git a/ext/standard/tests/strings/bug47443.phpt b/ext/standard/tests/strings/bug47443.phpt index e673e807ee85..de7d14483021 100644 --- a/ext/standard/tests/strings/bug47443.phpt +++ b/ext/standard/tests/strings/bug47443.phpt @@ -8,7 +8,12 @@ var_dump(metaphone("scrath")); var_dump(metaphone("scratc")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(4) "SKRX" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(4) "SKR0" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(5) "SKRTK" diff --git a/ext/standard/tests/strings/bug48709.phpt b/ext/standard/tests/strings/bug48709.phpt index 9e0789a61f24..65e42dd58c60 100644 --- a/ext/standard/tests/strings/bug48709.phpt +++ b/ext/standard/tests/strings/bug48709.phpt @@ -20,12 +20,27 @@ foreach ($exceptions as $letter) { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d kn => N + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d gn => N + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d pn => N + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d ae => E + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d wr => R + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d x => S + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d wh => W + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d wa => W diff --git a/ext/standard/tests/strings/metaphone.phpt b/ext/standard/tests/strings/metaphone.phpt index 6b8f5c1c89d9..bb2d30adf946 100644 --- a/ext/standard/tests/strings/metaphone.phpt +++ b/ext/standard/tests/strings/metaphone.phpt @@ -27,14 +27,31 @@ foreach($array as $str) { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(0) "" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(0) "" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d metaphone(): Argument #2 ($max_phonemes) must be greater than or equal to 0 + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(6) "FLTFRS" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(6) "FLTFRS" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(26) "0FLFRWRTKRFLNKHTLSLN0KLTR0" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(56) "BT0XTFHRRHLTNTRTRNTPSNKLWRNRFTBF0MSWPNK0FNRKW0TSFSTLWNKS" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(69) "ANT0NTWSKNFLYNKBKTMRTRW00SPTF0R0FSRNNTBHNTT0WNTRRTWLFNK0TTMRXSBRNTBLK" + +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d string(56) "0NKTWSTSFRS0YKLTPRSFNT0TSTNTMNSF0MNTNSWSTPLTW00FTFLMNLFT" Done diff --git a/ext/standard/tests/strings/metaphone_deprecation.phpt b/ext/standard/tests/strings/metaphone_deprecation.phpt new file mode 100644 index 000000000000..6e83b7abc036 --- /dev/null +++ b/ext/standard/tests/strings/metaphone_deprecation.phpt @@ -0,0 +1,11 @@ +--TEST-- +metaphone() deprecation +--FILE-- + +--EXPECTF-- +Deprecated: Function metaphone() is deprecated since 8.6, use a userland phonetic matching library instead in %s on line %d +string(7) "PRKRMNK" From 11047a7a6688b2360c3c3a26370caa39862a2587 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 10 Aug 2026 08:43:15 -0400 Subject: [PATCH 23/25] Fix use-after-free when __clone() retains the stylesheet copy importStylesheet() clones the stylesheet document and hands the copy to libxslt, which owns it and frees it together with the stylesheet. The clone goes through zend_objects_clone_members(), so a DOMDocument subclass __clone() can retain the copy, or a node proxy into it, and dereference freed memory once the processor is destroyed. Require the clone to be exclusively owned before libxslt takes it. Closes GH-23199 --- NEWS | 4 ++ ...ortStylesheet_clone_retained_document.phpt | 47 +++++++++++++++++++ .../importStylesheet_clone_retained_node.phpt | 34 ++++++++++++++ ext/xsl/xsltprocessor.c | 6 +++ 4 files changed, 91 insertions(+) create mode 100644 ext/xsl/tests/importStylesheet_clone_retained_document.phpt create mode 100644 ext/xsl/tests/importStylesheet_clone_retained_node.phpt diff --git a/NEWS b/NEWS index d19e6b8ae2af..6447fa7bc881 100644 --- a/NEWS +++ b/NEWS @@ -87,6 +87,10 @@ PHP NEWS . Fixed out-of-bounds write when shm_attach() opens an existing segment with a size larger than the segment actually is. (David Carlier) +- XSL: + . Fixed use-after-free when a DOMDocument subclass __clone() retains the + stylesheet copy made by XSLTProcessor::importStylesheet(). (iliaal) + - Zip: . Fixed ZipArchive::addGlob() and ZipArchive::addPattern() ignoring their default options when no options array is given. (David Carlier) diff --git a/ext/xsl/tests/importStylesheet_clone_retained_document.phpt b/ext/xsl/tests/importStylesheet_clone_retained_document.phpt new file mode 100644 index 000000000000..481925677d4e --- /dev/null +++ b/ext/xsl/tests/importStylesheet_clone_retained_document.phpt @@ -0,0 +1,47 @@ +--TEST-- +XSLTProcessor::importStylesheet() rejects a stylesheet whose __clone() retains the cloned document +--EXTENSIONS-- +dom +xsl +--FILE-- + + + + +XML; + +class Harmless extends DOMDocument { + public function __clone(): void { + } +} + +class RetainsDocument extends DOMDocument { + public function __clone(): void { + $GLOBALS['stash'] = $this; + } +} + +$doc = new Harmless; +$doc->loadXML(STYLESHEET); +$proc = new XSLTProcessor(); +var_dump($proc->importStylesheet($doc)); +unset($proc, $doc); + +$doc = new RetainsDocument; +$doc->loadXML(STYLESHEET); +$proc = new XSLTProcessor(); +try { + var_dump($proc->importStylesheet($doc)); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} +$kept = $GLOBALS['stash']; +unset($GLOBALS['stash'], $proc, $doc); +echo get_class($kept), " is still usable: ", $kept->documentElement->nodeName, PHP_EOL; +?> +--EXPECT-- +bool(true) +ValueError: XSLTProcessor::importStylesheet(): Argument #1 ($stylesheet) must not have its clone retained by __clone() +RetainsDocument is still usable: xsl:stylesheet diff --git a/ext/xsl/tests/importStylesheet_clone_retained_node.phpt b/ext/xsl/tests/importStylesheet_clone_retained_node.phpt new file mode 100644 index 000000000000..72c47b73b002 --- /dev/null +++ b/ext/xsl/tests/importStylesheet_clone_retained_node.phpt @@ -0,0 +1,34 @@ +--TEST-- +XSLTProcessor::importStylesheet() rejects a stylesheet whose __clone() retains a node of the cloned document +--EXTENSIONS-- +dom +xsl +--FILE-- +documentElement; + } +} + +$doc = new RetainsElement; +$doc->loadXML(<< + + + +XML); + +$proc = new XSLTProcessor(); +try { + var_dump($proc->importStylesheet($doc)); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} +$kept = $GLOBALS['stash']; +unset($GLOBALS['stash'], $proc, $doc); +echo get_class($kept), " is still usable: ", $kept->nodeName, PHP_EOL; +?> +--EXPECT-- +ValueError: XSLTProcessor::importStylesheet(): Argument #1 ($stylesheet) must not have its clone retained by __clone() +DOMElement is still usable: xsl:stylesheet diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 71971332a251..cf5a941d95ca 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -227,6 +227,12 @@ PHP_METHOD(XSLTProcessor, importStylesheet) php_libxml_node_object *clone_lxml_obj = Z_LIBXML_NODE_P(&clone_zv); + if (GC_REFCOUNT(clone) > 1 || clone_lxml_obj->document->refcount > 1) { + OBJ_RELEASE(clone); + zend_argument_value_error(1, "must not have its clone retained by __clone()"); + RETURN_THROWS(); + } + PHP_LIBXML_SANITIZE_GLOBALS(parse); ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") xmlSubstituteEntitiesDefault(1); From a49acfa9a7aeaa44a0c49bea15058d97d9238960 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 10 Aug 2026 21:02:56 +0100 Subject: [PATCH 24/25] standard: deprecate passing objects to http_build_query() (#23202) RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_data_parameter_of_http_build_query --- ext/standard/http.c | 15 ++++++++++++--- .../tests/http/http_build_query/bug26817.phpt | 5 ++++- .../http_build_query_object_basic.phpt | 3 ++- .../http_build_query_object_empty.phpt | 3 ++- .../http_build_query_object_just_stringable.phpt | 9 ++++++++- ...ttp_build_query_object_key_val_stringable.phpt | 3 ++- .../http_build_query_object_nested.phpt | 5 ++++- .../http_build_query_object_recursif.phpt | 5 ++++- .../http_build_query_variation1.phpt | 5 ++++- 9 files changed, 42 insertions(+), 11 deletions(-) diff --git a/ext/standard/http.c b/ext/standard/http.c index d65e7a8acaae..eee1018672bd 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -158,6 +158,11 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, if (Z_TYPE_P(zdata) == IS_ARRAY || (Z_TYPE_P(zdata) == IS_OBJECT && !(Z_OBJCE_P(zdata)->ce_flags & ZEND_ACC_ENUM))) { + if (Z_TYPE_P(zdata) == IS_OBJECT) { + php_error_docref(NULL, E_DEPRECATED, + "object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated," + " instead the $data argument should be preprocessed with get_object_vars()"); + } zend_string *new_prefix; if (key) { zend_string *encoded_key; @@ -236,9 +241,13 @@ PHP_FUNCTION(http_build_query) Z_PARAM_LONG(enc_type) ZEND_PARSE_PARAMETERS_END(); - if (UNEXPECTED(Z_TYPE_P(formdata) == IS_OBJECT && (Z_OBJCE_P(formdata)->ce_flags & ZEND_ACC_ENUM))) { - zend_argument_type_error(1, "must not be an enum, %s given", zend_zval_value_name(formdata)); - RETURN_THROWS(); + if (UNEXPECTED(Z_TYPE_P(formdata) == IS_OBJECT)) { + if (Z_OBJCE_P(formdata)->ce_flags & ZEND_ACC_ENUM) { + zend_argument_type_error(1, "must not be an enum, %s given", zend_zval_value_name(formdata)); + RETURN_THROWS(); + } + php_error_docref(NULL, E_DEPRECATED, + "Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead"); } php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, /* key_prefix */ NULL, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep, (int)enc_type); diff --git a/ext/standard/tests/http/http_build_query/bug26817.phpt b/ext/standard/tests/http/http_build_query/bug26817.phpt index e3b6539a1ccc..2014cbadf2ea 100644 --- a/ext/standard/tests/http/http_build_query/bug26817.phpt +++ b/ext/standard/tests/http/http_build_query/bug26817.phpt @@ -21,6 +21,9 @@ $obj = new test(); $obj->foo(); var_dump(http_build_query($obj)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(27) "foo=lala&bar=meuh&test=test" + +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(9) "test=test" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_basic.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_basic.phpt index 91bb8fc62295..4b9a4da49593 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_basic.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_basic.phpt @@ -13,5 +13,6 @@ $o = new KeyVal(); // Percent encoded "public=input" var_dump(http_build_query($o)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(12) "public=input" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_empty.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_empty.phpt index 7aca03df4a66..f154d1169040 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_empty.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_empty.phpt @@ -7,5 +7,6 @@ $o = new EmptyObj(); var_dump(http_build_query($o)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(0) "" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_just_stringable.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_just_stringable.phpt index 4c65547b81c8..9f19ba9d31b1 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_just_stringable.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_just_stringable.phpt @@ -15,8 +15,15 @@ var_dump(http_build_query($o)); var_dump(http_build_query(['hello', $o], numeric_prefix: 'prefix_')); var_dump(http_build_query($o, numeric_prefix: 'prefix_')); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated, instead the $data argument should be preprocessed with get_object_vars() in %s on line %d string(7) "0=hello" + +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(0) "" + +Deprecated: http_build_query(): object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated, instead the $data argument should be preprocessed with get_object_vars() in %s on line %d string(14) "prefix_0=hello" + +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(0) "" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_key_val_stringable.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_key_val_stringable.phpt index 2a738df362ae..dfcdde9b6693 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_key_val_stringable.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_key_val_stringable.phpt @@ -16,5 +16,6 @@ $o = new KeyValStringable(); var_dump(http_build_query($o)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d string(12) "public=input" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_nested.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_nested.phpt index 125327f0af00..6bb3912ff215 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_nested.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_nested.phpt @@ -16,5 +16,8 @@ $o->public = $nested; // Percent encoded "public[public]=input" var_dump(http_build_query($o)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: http_build_query(): object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated, instead the $data argument should be preprocessed with get_object_vars() in %s on line %d string(24) "public%5Bpublic%5D=input" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_object_recursif.phpt b/ext/standard/tests/http/http_build_query/http_build_query_object_recursif.phpt index ec415fc115b4..132a8b4242a1 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_object_recursif.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_object_recursif.phpt @@ -13,5 +13,8 @@ $o->public = $o; var_dump(http_build_query($o)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d + +Deprecated: http_build_query(): object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated, instead the $data argument should be preprocessed with get_object_vars() in %s on line %d string(0) "" diff --git a/ext/standard/tests/http/http_build_query/http_build_query_variation1.phpt b/ext/standard/tests/http/http_build_query/http_build_query_variation1.phpt index d1eaffb25b4a..3f00469433e8 100644 --- a/ext/standard/tests/http/http_build_query/http_build_query_variation1.phpt +++ b/ext/standard/tests/http/http_build_query/http_build_query_variation1.phpt @@ -20,6 +20,9 @@ $obj->sort = 'desc,name'; echo http_build_query($obj) . PHP_EOL; echo http_build_query(new UrlBuilder()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d name=homepage&page=1&sort=desc%2Cname + +Deprecated: http_build_query(): Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead in %s on line %d name=homepage&page=1 From c383b8cae02338f32d2fa460f003223003df1acb Mon Sep 17 00:00:00 2001 From: NickSdot <32384907+NickSdot@users.noreply.github.com> Date: Tue, 11 Aug 2026 03:03:40 +0700 Subject: [PATCH 25/25] core: Deprecate using `namespace` as class constant name (#22964) RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_using_namespace_as_a_class_constant_name --- NEWS | 1 + UPGRADING | 1 + .../deprecate_namespace_class_constant.phpt | 67 +++++++++++++++++++ Zend/tests/grammar/semi_reserved_005.phpt | 3 +- Zend/zend_API.c | 3 + 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/deprecate_namespace_class_constant.phpt diff --git a/NEWS b/NEWS index 4ed01591ea4c..23f9fad2e3f4 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS operation depth. (iliaal) - Core: + . Deprecated "namespace" as a class constant name. (NickSdot) . Changed run-tests.php to run in parallel by default, using up to 10 automatically detected workers. Pass -j1 for sequential execution. (NickSdot) diff --git a/UPGRADING b/UPGRADING index 754157e75b22..424e4189057c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -441,6 +441,7 @@ PHP 8.6 UPGRADE NOTES ======================================== - Core: + . Using "namespace" as a class constant name is deprecated. . Specifying a return type of array|null / ?array for __debugInfo() is now deprecated. Specify array instead. . Returning values from __construct() and __destruct() is now deprecated. diff --git a/Zend/tests/deprecate_namespace_class_constant.phpt b/Zend/tests/deprecate_namespace_class_constant.phpt new file mode 100644 index 000000000000..c44ebbc258da --- /dev/null +++ b/Zend/tests/deprecate_namespace_class_constant.phpt @@ -0,0 +1,67 @@ +--TEST-- +Using "namespace" as a class constant name is deprecated +--FILE-- +value, PHP_EOL; +echo Sup::namespace, PHP_EOL; +echo Can::$namespace, PHP_EOL; +echo Can::namespace(), PHP_EOL; +echo constant('namespace'), PHP_EOL; + +?> +--EXPECTF-- +Deprecated: Declaring class constant called 'namespace' is deprecated in %s on line %d + +Deprecated: Declaring interface constant called 'namespace' is deprecated in %s on line %d + +Deprecated: Declaring enum constant called 'namespace' is deprecated in %s on line %d + +Deprecated: Declaring trait constant called 'namespace' is deprecated in %s on line %d + +Deprecated: Declaring enum constant called 'namespace' is deprecated in %s on line %d +class constant value +interface constant value +enum constant value +enum case value +trait constant value +property value +method value +global constant value diff --git a/Zend/tests/grammar/semi_reserved_005.phpt b/Zend/tests/grammar/semi_reserved_005.phpt index 4a9a19e11812..06c428eacbc3 100644 --- a/Zend/tests/grammar/semi_reserved_005.phpt +++ b/Zend/tests/grammar/semi_reserved_005.phpt @@ -160,7 +160,8 @@ echo Obj::__NAMESPACE__, PHP_EOL; echo "\nDone\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Declaring class constant called 'namespace' is deprecated in %s on line %d empty callable trait diff --git a/Zend/zend_API.c b/Zend/zend_API.c index d7ed141a3e1d..e47c489dcee7 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4821,6 +4821,9 @@ ZEND_API zend_class_constant *zend_declare_typed_class_constant(zend_class_entry if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_CLASS))) { zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, "A class constant must not be called 'class'; it is reserved for class name fetching"); + } else if (zend_string_equals_literal_ci(name, "namespace")) { + zend_error(E_DEPRECATED, "Declaring %s constant called 'namespace' is deprecated", + zend_get_object_type(ce)); } if (Z_TYPE_P(value) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(value))) {