mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Fixed Bug #53958 (Closures can't 'use' shared variables by value and by reference)
This commit is contained in:
parent
409c5a9c7b
commit
64351b7add
61
Zend/tests/bug53958.phpt
Normal file
61
Zend/tests/bug53958.phpt
Normal file
@ -0,0 +1,61 @@
|
||||
--TEST--
|
||||
Bug #53958 (Closures can't 'use' shared variables by value and by reference)
|
||||
--FILE--
|
||||
<?php
|
||||
// TEST 1
|
||||
$a = 1;
|
||||
$fn1 = function() use ($a) {echo "$a\n"; $a++;};
|
||||
$fn2 = function() use ($a) {echo "$a\n"; $a++;};
|
||||
$a = 5;
|
||||
$fn1(); // 1
|
||||
$fn2(); // 1
|
||||
$fn1(); // 1
|
||||
$fn2(); // 1
|
||||
|
||||
// TEST 2
|
||||
$b = 1;
|
||||
$fn1 = function() use (&$b) {echo "$b\n"; $b++;};
|
||||
$fn2 = function() use (&$b) {echo "$b\n"; $b++;};
|
||||
$b = 5;
|
||||
$fn1(); // 5
|
||||
$fn2(); // 6
|
||||
$fn1(); // 7
|
||||
$fn2(); // 8
|
||||
|
||||
// TEST 3
|
||||
$c = 1;
|
||||
$fn1 = function() use (&$c) {echo "$c\n"; $c++;};
|
||||
$fn2 = function() use ($c) {echo "$c\n"; $c++;};
|
||||
$c = 5;
|
||||
$fn1(); // 5
|
||||
$fn2(); // 1
|
||||
$fn1(); // 6
|
||||
$fn2(); // 1
|
||||
|
||||
// TEST 4
|
||||
$d = 1;
|
||||
$fn1 = function() use ($d) {echo "$d\n"; $d++;};
|
||||
$fn2 = function() use (&$d) {echo "$d\n"; $d++;};
|
||||
$d = 5;
|
||||
$fn1(); // 1
|
||||
$fn2(); // 5
|
||||
$fn1(); // 1
|
||||
$fn2(); // 6
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
5
|
||||
1
|
||||
6
|
||||
1
|
||||
1
|
||||
5
|
||||
1
|
||||
6
|
@ -192,6 +192,7 @@ ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args
|
||||
{
|
||||
HashTable *target = va_arg(args, HashTable*);
|
||||
zend_bool is_ref;
|
||||
zval *tmp;
|
||||
|
||||
if (Z_TYPE_PP(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) {
|
||||
is_ref = Z_TYPE_PP(p) & IS_LEXICAL_REF;
|
||||
@ -200,26 +201,32 @@ ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args
|
||||
zend_rebuild_symbol_table(TSRMLS_C);
|
||||
}
|
||||
if (zend_hash_quick_find(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, (void **) &p) == FAILURE) {
|
||||
if (is_ref) {
|
||||
zval *tmp;
|
||||
|
||||
if (is_ref) {
|
||||
ALLOC_INIT_ZVAL(tmp);
|
||||
Z_SET_ISREF_P(tmp);
|
||||
zend_hash_quick_add(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), (void**)&p);
|
||||
} else {
|
||||
p = &EG(uninitialized_zval_ptr);
|
||||
tmp = EG(uninitialized_zval_ptr);
|
||||
zend_error(E_NOTICE,"Undefined variable: %s", key->arKey);
|
||||
}
|
||||
} else {
|
||||
if (is_ref) {
|
||||
SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
|
||||
tmp = *p;
|
||||
} else if (Z_ISREF_PP(p)) {
|
||||
SEPARATE_ZVAL(p);
|
||||
ALLOC_INIT_ZVAL(tmp);
|
||||
ZVAL_COPY_VALUE(tmp, *p);
|
||||
Z_SET_REFCOUNT_P(tmp, 0);
|
||||
Z_UNSET_ISREF_P(tmp);
|
||||
} else {
|
||||
tmp = *p;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmp = *p;
|
||||
}
|
||||
if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, p, sizeof(zval*), NULL) == SUCCESS) {
|
||||
Z_ADDREF_PP(p);
|
||||
if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), NULL) == SUCCESS) {
|
||||
Z_ADDREF_P(tmp);
|
||||
}
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user