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); \
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
*
*
* \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.
* 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.
{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;
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;
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;
}
/* }}} */
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);
--- /dev/null
+--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===
#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"
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;