Commit a4bb03a84b8 for php
commit a4bb03a84b8a1d81d896fb7a8bf3267cdafc5405
Author: Tim Düsterhus <tim@tideways-gmbh.com>
Date: Sat Sep 26 09:44:28 2026 +0200
standard: Take `HashTable*` instead of `zval*` in `php_explode()` (#23910)
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 4b5eed39a7b..a97aa97e528 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -29,6 +29,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES
3. Module changes
========================
+- Standard:
+ . php_explode() now takes a HashTable* instead of a zval* to store the
+ resulting parts. It already expected the zval* to be IS_ARRAY.
+
========================
4. OpCode changes
========================
diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h
index 412a4a4fa7a..7b8f8a8d3da 100644
--- a/ext/standard/php_string.h
+++ b/ext/standard/php_string.h
@@ -50,7 +50,7 @@ PHPAPI zend_string *php_trim(zend_string *str, const char *what, size_t what_len
PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len);
PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_t allow_len, bool allow_tag_spaces);
PHPAPI void php_implode(const zend_string *delim, HashTable *arr, zval *return_value);
-PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit);
+PHPAPI void php_explode(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit);
PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end);
PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end);
diff --git a/ext/standard/string.c b/ext/standard/string.c
index bfe0c71795b..ddd3f31bf14 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -875,7 +875,7 @@ PHP_FUNCTION(wordwrap)
/* }}} */
/* {{{ php_explode */
-PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit)
+PHPAPI void php_explode(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit)
{
const char *p1 = ZSTR_VAL(str);
const char *endp = ZSTR_VAL(str) + ZSTR_LEN(str);
@@ -884,10 +884,10 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return
if (p2 == NULL) {
ZVAL_STR_COPY(&tmp, str);
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
+ zend_hash_next_index_insert_new(parts, &tmp);
} else {
- zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
- ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ zend_hash_real_init_packed(parts);
+ ZEND_HASH_FILL_PACKED(parts) {
do {
ZEND_HASH_FILL_GROW();
ZEND_HASH_FILL_SET_STR(zend_string_init_fast(p1, p2 - p1));
@@ -907,7 +907,7 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return
/* }}} */
/* {{{ php_explode_negative_limit */
-PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit)
+static void php_explode_negative_limit(const zend_string *delim, zend_string *str, HashTable *parts, zend_long limit)
{
#define EXPLODE_ALLOC_STEP 64
const char *p1 = ZSTR_VAL(str);
@@ -939,7 +939,7 @@ PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *st
/* limit is at least -1 therefore no need of bounds checking : i will be always less than found */
for (i = 0; i < to_return; i++) { /* this checks also for to_return > 0 */
ZVAL_STRINGL_FAST(&tmp, positions[i], (positions[i+1] - ZSTR_LEN(delim)) - positions[i]);
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
+ zend_hash_next_index_insert_new(parts, &tmp);
}
efree((void *)positions);
}
@@ -977,9 +977,9 @@ PHP_FUNCTION(explode)
}
if (limit > 1) {
- php_explode(delim, str, return_value, limit);
+ php_explode(delim, str, Z_ARRVAL_P(return_value), limit);
} else if (limit < 0) {
- php_explode_negative_limit(delim, str, return_value, limit);
+ php_explode_negative_limit(delim, str, Z_ARRVAL_P(return_value), limit);
} else {
ZVAL_STR_COPY(&tmp, str);
zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);