/* {{{ Count the number of elements in a variable (usually an array) */ PHP_FUNCTION(count) { zval *array; zend_long mode = COUNT_NORMAL; zend_long cnt;
if (mode != COUNT_NORMAL && mode != COUNT_RECURSIVE) { zend_argument_value_error(2, "must be either COUNT_NORMAL or COUNT_RECURSIVE"); RETURN_THROWS(); }
switch (Z_TYPE_P(array)) { case IS_NULL: /* Intentionally not converted to an exception */ php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable"); RETURN_LONG(0); break; case IS_ARRAY: if (mode != COUNT_RECURSIVE) { cnt = zend_array_count(Z_ARRVAL_P(array)); } else { cnt = php_count_recursive(Z_ARRVAL_P(array)); } RETURN_LONG(cnt); break; case IS_OBJECT: { zval retval; /* first, we check if the handler is defined */ if (Z_OBJ_HT_P(array)->count_elements) { RETVAL_LONG(1); if (SUCCESS == Z_OBJ_HT(*array)->count_elements(Z_OBJ_P(array), &Z_LVAL_P(return_value))) { return; } if (EG(exception)) { RETURN_THROWS(); } } /* if not and the object implements Countable we call its count() method */ if (instanceof_function(Z_OBJCE_P(array), zend_ce_countable)) { zend_call_method_with_0_params(Z_OBJ_P(array), NULL, NULL, "count", &retval); if (Z_TYPE(retval) != IS_UNDEF) { RETVAL_LONG(zval_get_long(&retval)); zval_ptr_dtor(&retval); } return; }
/* If There's no handler and it doesn't implement Countable then add a warning */ /* Intentionally not converted to an exception */ php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable"); RETURN_LONG(1); break; } default: /* Intentionally not converted to an exception */ php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable"); RETURN_LONG(1); break; } } /* }}} */