From 8e3a8b1e8edb23613c5785d0ee2a3104c8a8d616 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Mon, 1 Nov 2004 10:45:54 +0000 Subject: [PATCH] - Add interface Countable (PECL #30113) --- ext/spl/php_spl.c | 1 + ext/spl/spl.php | 14 ++++++++++++-- ext/spl/spl_array.c | 11 +++++++++++ ext/spl/spl_array.h | 1 + ext/spl/tests/spl_002.phpt | 22 ++++++++++++++++++++++ ext/standard/array.c | 15 ++++++++++++++- 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100755 ext/spl/tests/spl_002.phpt diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index c3f6b7599b..55f4369dd5 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -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); \ diff --git a/ext/spl/spl.php b/ext/spl/spl.php index 6fb92b267d..4cf429d71c 100755 --- a/ext/spl/spl.php +++ b/ext/spl/spl.php @@ -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. diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index f68fbef31c..d13b36f2da 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -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; } /* }}} */ diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index cf29ae439e..f075be6f91 100755 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -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 index 0000000000..d8b71b20cf --- /dev/null +++ b/ext/spl/tests/spl_002.phpt @@ -0,0 +1,22 @@ +--TEST-- +SPL: Countable +--FILE-- + +===DONE=== +--EXPECT-- +int(4) +===DONE=== diff --git a/ext/standard/array.c b/ext/standard/array.c index b346da25b2..218bbfb7f5 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -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; -- 2.40.0