Commit 9060fd33665 for php.net
commit 9060fd336657b93986e5934d5abb380a6bc19eb3
Author: mehmetcan <2010841+mehmetcansahin@users.noreply.github.com>
Date: Mon Jun 29 19:43:29 2026 +0300
Move min/max array fallback into array.c (#22147)
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index a467df3b6be..a8eb6b80541 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -36,6 +36,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
. The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed.
Call zval_ptr_dtor_nogc() directly instead.
. The internal zend_copy_parameters_array() function is no longer exposed.
+ . The internal zend_hash_minmax() function is no longer exposed. Scan the
+ HashTable directly and use zend_compare() for value comparisons instead.
. The zend_make_callable() function has been removed, if a callable zval
needs to be obtained use the zend_get_callable_zval_from_fcc() function
instead. If this was used to store a callable, then an FCC should be
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 2913af9c2b5..acc342bc267 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -3238,73 +3238,6 @@ ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_fun
}
-ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag)
-{
- uint32_t idx;
- zval *res;
-
- IS_CONSISTENT(ht);
-
- if (ht->nNumOfElements == 0 ) {
- return NULL;
- }
-
- if (HT_IS_PACKED(ht)) {
- zval *zv;
-
- idx = 0;
- while (1) {
- if (idx == ht->nNumUsed) {
- return NULL;
- }
- if (Z_TYPE(ht->arPacked[idx]) != IS_UNDEF) break;
- idx++;
- }
- res = ht->arPacked + idx;
- for (; idx < ht->nNumUsed; idx++) {
- zv = ht->arPacked + idx;
- if (UNEXPECTED(Z_TYPE_P(zv) == IS_UNDEF)) continue;
-
- if (flag) {
- if (compar(res, zv) < 0) { /* max */
- res = zv;
- }
- } else {
- if (compar(res, zv) > 0) { /* min */
- res = zv;
- }
- }
- }
- } else {
- Bucket *p;
-
- idx = 0;
- while (1) {
- if (idx == ht->nNumUsed) {
- return NULL;
- }
- if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) break;
- idx++;
- }
- res = &ht->arData[idx].val;
- for (; idx < ht->nNumUsed; idx++) {
- p = ht->arData + idx;
- if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
-
- if (flag) {
- if (compar(res, &p->val) < 0) { /* max */
- res = &p->val;
- }
- } else {
- if (compar(res, &p->val) > 0) { /* min */
- res = &p->val;
- }
- }
- }
- }
- return res;
-}
-
ZEND_API bool ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx)
{
const char *tmp = key;
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 6c0d4a241a1..1181bee29fa 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -303,7 +303,6 @@ typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b);
ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered);
ZEND_API void ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber);
ZEND_API void ZEND_FASTCALL zend_array_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber);
-ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag);
static zend_always_inline void ZEND_FASTCALL zend_hash_sort(HashTable *ht, bucket_compare_func_t compare_func, bool renumber) {
zend_hash_sort_ex(ht, zend_sort, compare_func, renumber);
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 3b17ca3f794..a233e6c4dcb 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1089,9 +1089,23 @@ PHP_FUNCTION(key)
}
/* }}} */
-static int php_data_compare(const void *f, const void *s) /* {{{ */
+static zval *php_array_data_minmax(HashTable *array, bool max) /* {{{ */
{
- return zend_compare((zval*)f, (zval*)s);
+ zval *entry, *result = NULL;
+
+ ZEND_HASH_FOREACH_VAL(array, entry) {
+ if (!result) {
+ result = entry;
+ continue;
+ }
+
+ int cmp = zend_compare(result, entry);
+ if (max ? cmp < 0 : cmp > 0) {
+ result = entry;
+ }
+ } ZEND_HASH_FOREACH_END();
+
+ return result;
}
/* }}} */
@@ -1114,7 +1128,7 @@ PHP_FUNCTION(min)
zend_wrong_parameter_type_error(1, Z_EXPECTED_ARRAY, &args[0]);
RETURN_THROWS();
} else {
- zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 0);
+ zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), false);
if (result) {
RETURN_COPY_DEREF(result);
} else {
@@ -1242,7 +1256,7 @@ PHP_FUNCTION(max)
zend_wrong_parameter_type_error(1, Z_EXPECTED_ARRAY, &args[0]);
RETURN_THROWS();
} else {
- zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 1);
+ zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), true);
if (result) {
RETURN_COPY_DEREF(result);
} else {