[php-src] master: Move min/max array fallback into array.c (#22147)

mehmetcan via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: mehmetcan (mehmetcansahin)
Committer: GitHub (web-flow)
Pusher: Girgias
Date: 2026-06-29T17:43:29+01:00

Commit: https://github.com/php/php-src/commit/9060fd336657b93986e5934d5abb380a6bc19eb3
Raw diff: https://github.com/php/php-src/commit/9060fd336657b93986e5934d5abb380a6bc19eb3.diff

Move min/max array fallback into array.c (#22147)

Changed paths:
  M  UPGRADING.INTERNALS
  M  Zend/zend_hash.c
  M  Zend/zend_hash.h
  M  ext/standard/array.c


Diff:

diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index a467df3b6be5..a8eb6b805413 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 2913af9c2b5f..acc342bc267d 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 6c0d4a241a1b..1181bee29fae 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 3b17ca3f7942..a233e6c4dcb5 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 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.