diff options
author | Marcus Boerger <helly@php.net> | 2003-10-24 18:24:28 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2003-10-24 18:24:28 +0000 |
commit | 071eaf857633f36fb2b8748b3b08b3cac41f05bc (patch) | |
tree | 6c2bd2efc3fe0775017033609ad6d75bbf0fb565 | |
parent | 074ca4539964d736f3a31a4fb10f4eabd77addfa (diff) | |
download | php-git-071eaf857633f36fb2b8748b3b08b3cac41f05bc.tar.gz |
Zend/ZEND_CHANGES
-rw-r--r-- | Zend/ZEND_CHANGES | 73 | ||||
-rw-r--r-- | Zend/zend_API.c | 17 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 24 | ||||
-rw-r--r-- | ext/sockets/sockets.c | 11 |
4 files changed, 111 insertions, 14 deletions
diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES index 87cb5ee4d6..988c8f7133 100644 --- a/Zend/ZEND_CHANGES +++ b/Zend/ZEND_CHANGES @@ -651,6 +651,79 @@ Changes in the Zend Engine 2.0 TBD: Respect visibility: Show protected only when inside class method and only otherwise public properties only. + Each class whose instances can be iterated with foreach should + implement the empty interface 'Traversable'. Hence any object + that says it implements 'Traversable' can be used with forach. + + The interfaces 'IteratorAggregate' and 'Iterator' allow to specify + how class objects are iterated in PHP code. The first of them simply + has a method 'getIterator' which must return an array or an object + that either implements the interface 'Iterator' or is instantiated + from an internal class that can be iterated. + + Example: + + <?php + class ObjectIterator implements Iterator { + + private $obj; + private $num; + + function __construct($obj) { + $this->obj = $obj; + } + function rewind() { + $this->num = 0; + } + function hasMore() { + return $this->num < $this->obj->max; + } + function key() { + return $this->num; + } + function current() { + switch($this->num) { + case 0: return "1st"; + case 1: return "2nd"; + case 2: return "3rd"; + default: return $this->num."th"; + } + } + function next() { + $this->num++; + } + } + + class Oject implements IteratorAggregate { + + public $max = 3; + + function getIterator() { + return new ObjectIterator($this); + } + } + + $obj = new Object; + + // this foreach ... + foreach($obj as $key => $val) { + echo "$key = $val\n"; + } + + // matches the following 7 lines with the for directive. + $it = $obj->getIterator(); + for($it->rewind(); $it->hasMore(); $it->next) { + $key = $it->current(); + $val = $it->key(); + echo "$key = $val\n"; + } + unset($it); + ?> + + The matching for directive is very intersting here since it shows + the use of all abstract methods declared in the interfaces Iterator + and IteratorAggregate respectively. + * __METHOD__ The pseudo constant __METHOD__ shows the current class and method diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f9a868ddda..575d9daaa4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1588,8 +1588,23 @@ zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callabl return 1; lcname = zend_str_tolower_dup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); - if (zend_hash_exists(EG(function_table), lcname, Z_STRLEN_P(callable)+1)) + if (zend_hash_exists(EG(function_table), lcname, Z_STRLEN_P(callable)+1)) { retval = 1; + } else { + char *func_pos; + if ((func_pos=strstr(lcname, "::"))) { + int lcclass_len = (int)(func_pos - lcname); + char *lcclass = estrndup(lcname, lcclass_len); + zend_class_entry **ce; + + if (zend_lookup_class(lcclass, lcclass_len, &ce TSRMLS_CC) == SUCCESS) { + int func_len = Z_STRLEN_P(callable) - lcclass_len - 2; + func_pos += 2; + retval = zend_hash_exists(&(*ce)->function_table, func_pos, func_len + 1) ? 1 : 0; + } + efree(lcclass); + } + } efree(lcname); break; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 150b4f4a39..e18138228a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -532,7 +532,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_execute_data execute_data; zval *method_name; zval *params_array; - int call_via_handler = 0; + int call_via_handler = 0, success; + char *func_pos; switch (fci->size) { case sizeof(zend_fcall_info): @@ -616,7 +617,26 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS function_name_lc = zend_str_tolower_dup(fci->function_name->value.str.val, fci->function_name->value.str.len); - if (zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + success = zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function); + if (success==FAILURE && !fci->object_pp && (func_pos=strstr(function_name_lc, "::"))) { + int class_name_lc_len = (int)(func_pos - function_name_lc); + char *class_name_lc = estrndup(function_name_lc, class_name_lc_len); + zend_class_entry **ce; + + success = zend_lookup_class(class_name_lc, class_name_lc_len, &ce TSRMLS_CC); + + efree(class_name_lc); + if (success == SUCCESS) { + int func_len = fci->function_name->value.str.len - class_name_lc_len - 2; + func_pos += 2; + fci->function_table = &(*ce)->function_table; + calling_scope = *ce; + fci->object_pp = NULL; + success = zend_hash_find(fci->function_table, func_pos, func_len + 1, (void **) &EX(function_state).function); + } + } + + if (success==FAILURE) { /* try calling __call */ if (calling_scope && calling_scope->__call) { EX(function_state).function = calling_scope->__call; diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index e1e0418bb6..57dbab5ae0 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -111,17 +111,6 @@ static ZEND_ARG_PASS_INFO(1) ZEND_END_ARG_INFO(); -static - ZEND_BEGIN_ARG_INFO(third_through_seventh_args_force_ref, 0) - ZEND_ARG_PASS_INFO(0) - ZEND_ARG_PASS_INFO(0) - ZEND_ARG_PASS_INFO(1) - ZEND_ARG_PASS_INFO(1) - ZEND_ARG_PASS_INFO(1) - ZEND_ARG_PASS_INFO(1) - ZEND_ARG_PASS_INFO(1) - ZEND_END_ARG_INFO(); - /* {{{ sockets_functions[] */ function_entry sockets_functions[] = { |