- Add interface Countable (PECL #30113)

This commit is contained in:
Marcus Boerger 2004-11-01 10:45:54 +00:00
parent b557bdb665
commit 8e3a8b1e8e
6 changed files with 61 additions and 3 deletions

View File

@ -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); \

View File

@ -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.

View File

@ -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;
}
/* }}} */

View File

@ -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);

22
ext/spl/tests/spl_002.phpt Executable file
View File

@ -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===

View 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;