nikic · GitHub

@nikic

TysonAndre

Comment on lines 2584 to 2585

Contributor

  1. Should this handle [...new ArrayObject(['key' => ThrowsOnDestruct]), ...new CustomTraversable()] to avoid an call to CustomTraversable::valid() in the unlikely case that an exception was thrown when the overwritten value's destructor was called?
    (i.e. before iter->funcs->valid(iter) == SUCCESS is called again)

    (e.g. in case CustomTraversable modifies state, performs db operations or makes network service calls)

  2. nit: the original works correctly, but I wonder if the below snippet would be a tiny bit more efficient, because the C optimizer can't infer that Z_STR(key) doesn't change after the call to zend_hash_update(), which may call destructors which modify zval, etc.

Same for the other calls to zval_ptr_dtor_str() in this PR - I mostly see zval_ptr_dtor_str in this file places that the compiler can infer don't have side effects, such as zend_fast_equal_strings

Suggested change

zend_hash_update(result_ht, Z_STR(key), val);
zval_ptr_dtor_str(&key);
zend_string *key_str = Z_STR(key);
zend_hash_update(result_ht, key_str, val);
zend_string_release_ex(key_str, 0);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(val);
break;
}

TysonAndre

Comment on lines 2588 to 2589

And add opcache support.

@nikic

adrian-enspired pushed a commit to adrian-enspired/php-src that referenced this pull request

Aug 4, 2026

Read the original on github.com ↗