]> granicus.if.org Git - php/commitdiff
- Add interface Countable (PECL #30113)
authorMarcus Boerger <helly@php.net>
Mon, 1 Nov 2004 10:45:54 +0000 (10:45 +0000)
committerMarcus Boerger <helly@php.net>
Mon, 1 Nov 2004 10:45:54 +0000 (10:45 +0000)
ext/spl/php_spl.c
ext/spl/spl.php
ext/spl/spl_array.c
ext/spl/spl_array.h
ext/spl/tests/spl_002.phpt [new file with mode: 0755]
ext/standard/array.c

index c3f6b7599b53de46e301d449db3faa641bf8759b..55f4369dd5d137f94717c87658f8beef219ea1f8 100755 (executable)
@@ -166,6 +166,7 @@ PHP_FUNCTION(class_implements)
        SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags); \
        SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \
        SPL_ADD_CLASS(CachingRecursiveIterator, z_list, sub, allow, ce_flags); \
+       SPL_ADD_CLASS(Countable, z_list, sub, allow, ce_flags); \
        SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
        SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \
        SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \
index 6fb92b267d1220102ce6cf0b3193fd54f8972863..4cf429d71cd97dd5ae0c3da526bfa0bf7a4de9c3 100755 (executable)
@@ -169,6 +169,16 @@ class RecursiveIteratorIterator implements Iterator
        function getSubIterator([$level]);
 }
 
+/** @ingroup SPL
+ * @brief This Interface allows to hook into the global count() function.
+ */
+interface Countable
+{
+       /** @return the number the global function count() should show
+        */
+       function count();
+}
+
 /** \ingroup SPL
  * \brief An Array wrapper
  *
@@ -177,7 +187,7 @@ class RecursiveIteratorIterator implements Iterator
  *
  * \see ArrayIterator
  */
-class ArrayObject implements IteratorAggregate, ArrayAccess
+class ArrayObject implements IteratorAggregate, ArrayAccess, Countable
 {
        /** Construct a new array iterator from anything that has a hash table.
         * That is any Array or Object.
@@ -239,7 +249,7 @@ class ArrayObject implements IteratorAggregate, ArrayAccess
  * refer to it either by using foreach or by calling its getIterator() 
  * method manually.
  */
-class ArrayIterator implements Iterator, SeekableIterator, ArrayAccess
+class ArrayIterator implements Iterator, SeekableIterator, ArrayAccess, Countable
 {
        /** Construct a new array iterator from anything that has a hash table.
         * That is any Array or Object.
index f68fbef31c670702244d921fbdb7ce2f63dd9651..d13b36f2da919a20f8afbad95a2523975b7fdbc4 100755 (executable)
@@ -108,6 +108,10 @@ static zend_function_entry spl_funcs_ArrayIterator[] = {
        {NULL, NULL, NULL}
 };
 
+static zend_function_entry spl_funcs_Countable[] = {
+       SPL_ABSTRACT_ME(Countable, count,   NULL)
+       {NULL, NULL, NULL}
+};
 
 zend_object_handlers spl_handler_ArrayObject;
 zend_class_entry *   spl_ce_ArrayObject;
@@ -115,6 +119,8 @@ zend_class_entry *   spl_ce_ArrayObject;
 zend_object_handlers spl_handler_ArrayIterator;
 zend_class_entry *   spl_ce_ArrayIterator;
 
+zend_class_entry *spl_ce_Countable;
+
 typedef struct _spl_array_object {
        zend_object       std;
        zval              *array;
@@ -896,6 +902,11 @@ PHP_MINIT_FUNCTION(spl_array)
        memcpy(&spl_handler_ArrayIterator, &spl_handler_ArrayObject, sizeof(zend_object_handlers));
        spl_ce_ArrayIterator->get_iterator = spl_array_get_iterator;
 
+       REGISTER_SPL_INTERFACE(Countable);
+       
+       REGISTER_SPL_IMPLEMENTS(ArrayObject, Countable);
+       REGISTER_SPL_IMPLEMENTS(ArrayIterator, Countable);
+
        return SUCCESS;
 }
 /* }}} */
index cf29ae439e12104e1f7a2d382f704d078ae67163..f075be6f9103ddd6ae94e08cfa71e0f3a6c99184 100755 (executable)
@@ -26,6 +26,7 @@
 
 extern zend_class_entry *spl_ce_ArrayObject;
 extern zend_class_entry *spl_ce_ArrayIterator;
+extern zend_class_entry *spl_ce_Countable;
 
 PHP_MINIT_FUNCTION(spl_array);
 
diff --git a/ext/spl/tests/spl_002.phpt b/ext/spl/tests/spl_002.phpt
new file mode 100755 (executable)
index 0000000..d8b71b2
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+SPL: Countable
+--FILE--
+<?php
+
+class Test implements Countable
+{
+       function count()
+       {
+               return 4;
+       }
+};
+
+$a = new Test;
+
+var_dump(count($a));
+
+?>
+===DONE===
+--EXPECT--
+int(4)
+===DONE===
index b346da25b2b2b4ce829703b9aa542d2230a4f490..218bbfb7f5b45a53cadc8bb188f2b6068d20bd67 100644 (file)
@@ -39,6 +39,7 @@
 #include "win32/unistd.h"
 #endif
 #include "zend_globals.h"
+#include "zend_interfaces.h"
 #include "php_globals.h"
 #include "php_array.h"
 #include "basic_functions.h"
@@ -301,13 +302,25 @@ PHP_FUNCTION(count)
                case IS_ARRAY:
                        RETURN_LONG (php_count_recursive (array, mode TSRMLS_CC));
                        break;
-               case IS_OBJECT:
+               case IS_OBJECT: {
+#if HAVE_SPL
+                       zend_class_entry **pce = NULL;
+                       zval *retval;
+
+                       if (zend_lookup_class("countable", sizeof("countable")-1, &pce TSRMLS_CC) == SUCCESS) {
+                               zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
+                               RETVAL_LONG(Z_LVAL_P(retval));
+                               zval_ptr_dtor(&retval);
+                               return;
+                       }
+#endif
                        if (Z_OBJ_HT(*array)->count_elements) {
                                RETVAL_LONG(1);
                                if (SUCCESS == Z_OBJ_HT(*array)->count_elements(array, &Z_LVAL_P(return_value) TSRMLS_CC)) {
                                        return;
                                }
                        }
+               }
                default:
                        RETURN_LONG(1);
                        break;