]> granicus.if.org Git - php/commitdiff
Zend/ZEND_CHANGES
authorMarcus Boerger <helly@php.net>
Fri, 24 Oct 2003 18:24:28 +0000 (18:24 +0000)
committerMarcus Boerger <helly@php.net>
Fri, 24 Oct 2003 18:24:28 +0000 (18:24 +0000)
Zend/ZEND_CHANGES
Zend/zend_API.c
Zend/zend_execute_API.c
ext/sockets/sockets.c

index 87cb5ee4d655f6ea0aa40ab8bb6db308ad671c07..988c8f71330847ad0ff9a6f7cadf9e7c8e0f673d 100644 (file)
@@ -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 
index f9a868ddda687bcdf014d9e7fb1d5b0dd9c01a26..575d9daaa4add02825b656c0d93abb2ba339bb67 100644 (file)
@@ -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;
 
index 150b4f4a396c65c27aa080271fe6184e22ff66aa..e18138228add68c79aafab8d3b6cbbe325373c1a 100644 (file)
@@ -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;
index e1e0418bb67c9c9d5e74b532f2262c66d18c3f72..57dbab5ae0e23e791142fec4c64c74dac8c7a49e 100644 (file)
@@ -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[] = {