From b099670127063fd67c3d7f808e5d44f3cfb02716 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Mon, 4 Aug 2003 21:56:05 +0000 Subject: [PATCH] - Unset support for spl_array_access by method set($index) - Parameter names for array interface methods --- ext/spl/php_spl.c | 8 ++-- ext/spl/php_spl.h | 1 + ext/spl/spl_array.c | 60 +++++++++++++++++++++++++++++ ext/spl/spl_array.h | 1 + ext/spl/tests/array_access_001.phpt | 41 ++++++++++++++++++++ ext/spl/tests/array_access_002.phpt | 4 ++ 6 files changed, 112 insertions(+), 3 deletions(-) diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 6634e156b5..9704fe261d 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -95,6 +95,7 @@ static void spl_init_globals(zend_spl_globals *spl_globals) #ifdef SPL_ARRAY_WRITE ZEND_EXECUTE_HOOK(ZEND_ASSIGN_DIM); + ZEND_EXECUTE_HOOK(ZEND_UNSET_DIM_OBJ); #endif /* SPL_ARRAY_WRITE */ } /* }}} */ @@ -106,13 +107,13 @@ PHP_FUNCTION(spl_abstract) {} static ZEND_BEGIN_ARG_INFO(arginfo_one_param, 0) - ZEND_ARG_PASS_INFO(0) + ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO(); static ZEND_BEGIN_ARG_INFO(arginfo_two_params, 0) - ZEND_ARG_PASS_INFO(0) - ZEND_ARG_PASS_INFO(0) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO(); function_entry spl_funcs_iterator[] = { @@ -148,6 +149,7 @@ function_entry spl_funcs_array_read[] = { function_entry spl_funcs_array_access[] = { SPL_ABSTRACT_FE(array_access, set, arginfo_two_params) + SPL_ABSTRACT_FE(array_access, del, arginfo_one_param) {NULL, NULL, NULL} }; diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 7591ef8c50..b8de833022 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -71,6 +71,7 @@ ZEND_BEGIN_MODULE_GLOBALS(spl) #endif #ifdef SPL_ARRAY_WRITE ZEND_EXECUTE_HOOK_PTR(ZEND_ASSIGN_DIM); + ZEND_EXECUTE_HOOK_PTR(ZEND_UNSET_DIM_OBJ); #endif ZEND_END_MODULE_GLOBALS(spl) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 55be32069a..d728942a49 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -240,6 +240,66 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN_DIM) #endif /* }}} */ +/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_UNSET_DIM_OBJ) */ +#ifdef SPL_ARRAY_WRITE +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_UNSET_DIM_OBJ) +{ + zval **obj; + zend_class_entry *obj_ce; + spl_is_a is_a; + + if (EX(opline)->extended_value != ZEND_UNSET_DIM) { + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_UNSET_DIM_OBJ); + } + + obj = spl_get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), 0 TSRMLS_CC); + + if (!obj || (obj_ce = spl_get_class_entry(*obj TSRMLS_CC)) == NULL) { + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_UNSET_DIM_OBJ); + } + + is_a = spl_implements(obj_ce); + + if (is_a & SPL_IS_A_ARRAY_ACCESS) { + znode *op2 = &EX(opline)->op2; + zval *index = spl_get_zval_ptr(op2, EX(Ts), &EG(free_op2), BP_VAR_R); + zval tmp; + zval *retval; + + spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); + + /* here we are sure we are dealing with an object */ + switch (op2->op_type) { + case IS_CONST: + /* already a constant string */ + break; + case IS_VAR: + tmp = *index; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + index = &tmp; + break; + case IS_TMP_VAR: + convert_to_string(index); + break; + } + + spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "del", sizeof("del")-1, &retval, index TSRMLS_CC); + + if (index == &tmp) { + zval_dtor(index); + } + + FREE_OP(Ts, op2, EG(free_op2)); + DELETE_RET_ZVAL(retval); + + NEXT_OPCODE(); + } + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_UNSET_DIM_OBJ); +} +#endif +/* }}} */ + SPL_CLASS_FUNCTION(array, __construct); SPL_CLASS_FUNCTION(array, new_iterator); SPL_CLASS_FUNCTION(array, rewind); diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index 3aa194c8cc..840a9627eb 100755 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -30,6 +30,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW); #ifdef SPL_ARRAY_WRITE ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN_DIM); +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_UNSET_DIM_OBJ); #endif #endif /* SPL_ARRAY_H */ diff --git a/ext/spl/tests/array_access_001.phpt b/ext/spl/tests/array_access_001.phpt index 4aea3d90f4..2292749db2 100755 --- a/ext/spl/tests/array_access_001.phpt +++ b/ext/spl/tests/array_access_001.phpt @@ -22,6 +22,10 @@ class c implements spl_array_access { echo __METHOD__ . "($index,$newval)\n"; return $this->a[$index] = $newval; } + function del($index) { + echo __METHOD__ . "($index)\n"; + unset($this->a[$index]); + } } $obj = new c(); @@ -55,6 +59,14 @@ $x = $obj[6] = 'changed 6'; var_dump($obj[6]); var_dump($x); +echo "===unset===\n"; +var_dump($obj->a); +unset($obj[2]); +unset($obj['4th']); +unset($obj[7]); +unset($obj['8th']); +var_dump($obj->a); + print "Done\n"; ?> --EXPECTF-- @@ -119,4 +131,33 @@ c::exists(6) c::get(6) string(9) "changed 6" string(9) "changed 6" +===unset=== +array(6) { + [0]=> + string(3) "1st" + [1]=> + string(9) "Changed 1" + [2]=> + string(3) "3rd" + ["4th"]=> + string(11) "Changed 4th" + ["5th"]=> + string(9) "Added 5th" + [6]=> + string(9) "changed 6" +} +c::del(2) +c::del(4th) +c::del(7) +c::del(8th) +array(4) { + [0]=> + string(3) "1st" + [1]=> + string(9) "Changed 1" + ["5th"]=> + string(9) "Added 5th" + [6]=> + string(9) "changed 6" +} Done diff --git a/ext/spl/tests/array_access_002.phpt b/ext/spl/tests/array_access_002.phpt index e6616ea658..133e6f3f4a 100755 --- a/ext/spl/tests/array_access_002.phpt +++ b/ext/spl/tests/array_access_002.phpt @@ -23,6 +23,10 @@ class c implements spl_array_access { echo __METHOD__ . "($index,$newval)\n"; /* return */ $this->a[$index] = $newval; } + function del($index) { + echo __METHOD__ . "($index)\n"; + unset($this->a[$index]); + } } $obj = new c(); -- 2.40.0