diff options
author | Gabriel Caruso <carusogabriel34@gmail.com> | 2018-01-19 20:01:40 -0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2018-03-11 16:41:16 +0100 |
commit | d0ee2a8254c69546c7191ac26cdc0499eba27acf (patch) | |
tree | 0607e58a4afb3b439c8f2a98b466fda472c3c33c | |
parent | 57896cf5158732101d6e09843b34f6b5f8fbba8a (diff) | |
download | php-git-d0ee2a8254c69546c7191ac26cdc0499eba27acf.tar.gz |
Add is_countable function
RFC: https://wiki.php.net/rfc/is-countable
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | UPGRADING | 6 | ||||
-rw-r--r-- | Zend/zend_API.c | 17 | ||||
-rw-r--r-- | Zend/zend_API.h | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_func_info.c | 1 | ||||
-rw-r--r-- | ext/standard/basic_functions.c | 5 | ||||
-rw-r--r-- | ext/standard/php_type.h | 1 | ||||
-rw-r--r-- | ext/standard/tests/general_functions/is_countable_with_classes.phpt | 19 | ||||
-rw-r--r-- | ext/standard/tests/general_functions/is_countable_with_variables.phpt | 32 | ||||
-rw-r--r-- | ext/standard/type.c | 14 |
10 files changed, 96 insertions, 2 deletions
@@ -171,6 +171,7 @@ PHP NEWS . Updated bundled libsqlite to 3.22.0. (cmb) - Standard: + . Added is_countable() function. (Gabriel Caruso) . Fixed bug #75916 (DNS_CAA record results contain garbage). (Mike, Philip Sharp) . Fixed unserialize(), to disable creation of unsupported data structures @@ -129,8 +129,10 @@ Intl: URestrictionLevel under http://icu-project.org/apiref/icu4c/uspoof_8h.html -SPL: - . Added spl_object_id(). +Standard: + . Added is_countable() function, to check whether a value may be passed to + count(). + (RFC: https://wiki.php.net/rfc/is-countable) ======================================== 7. New Classes and Interfaces diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ca68310bc9..924457916d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4379,6 +4379,23 @@ ZEND_API zend_bool zend_is_iterable(zval *iterable) /* {{{ */ } /* }}} */ +ZEND_API zend_bool zend_is_countable(zval *countable) /* {{{ */ +{ + switch (Z_TYPE_P(countable)) { + case IS_ARRAY: + return 1; + case IS_OBJECT: + if (Z_OBJ_HT_P(countable)->count_elements) { + return 1; + } + + return instanceof_function(Z_OBJCE_P(countable), zend_ce_countable); + default: + return 0; + } +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 132ff1cfaf..385c5f1744 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -562,6 +562,8 @@ ZEND_API const char *zend_get_object_type(const zend_class_entry *ce); ZEND_API zend_bool zend_is_iterable(zval *iterable); +ZEND_API zend_bool zend_is_countable(zval *countable); + #define add_method(arg, key, method) add_assoc_function((arg), (key), (method)) ZEND_API ZEND_FUNCTION(display_disabled_function); diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 2df0113b79..8ec9195511 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -610,6 +610,7 @@ static const func_info_t func_infos[] = { F0("is_object", MAY_BE_FALSE | MAY_BE_TRUE), // TODO: inline with support for incomplete class F0("is_scalar", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), F0("is_callable", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), + F0("is_countable", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), F0("pclose", MAY_BE_FALSE | MAY_BE_LONG), F1("popen", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), F0("readfile", MAY_BE_FALSE | MAY_BE_LONG), diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index a0ad3b3619..95281705dc 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2586,6 +2586,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_is_iterable, 0, 0, 1) ZEND_ARG_INFO(0, var) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_is_countable, 0) + ZEND_ARG_INFO(0, var) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ uniqid.c */ #ifdef HAVE_GETTIMEOFDAY @@ -3111,6 +3115,7 @@ static const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(is_scalar, arginfo_is_scalar) PHP_FE(is_callable, arginfo_is_callable) PHP_FE(is_iterable, arginfo_is_iterable) + PHP_FE(is_countable, arginfo_is_countable) /* functions from file.c */ PHP_FE(pclose, arginfo_pclose) diff --git a/ext/standard/php_type.h b/ext/standard/php_type.h index 0d003f5538..845c206c1f 100644 --- a/ext/standard/php_type.h +++ b/ext/standard/php_type.h @@ -39,5 +39,6 @@ PHP_FUNCTION(is_object); PHP_FUNCTION(is_scalar); PHP_FUNCTION(is_callable); PHP_FUNCTION(is_iterable); +PHP_FUNCTION(is_countable); #endif diff --git a/ext/standard/tests/general_functions/is_countable_with_classes.phpt b/ext/standard/tests/general_functions/is_countable_with_classes.phpt new file mode 100644 index 0000000000..ebf7ac5dc9 --- /dev/null +++ b/ext/standard/tests/general_functions/is_countable_with_classes.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test is_countable() function +--CREDITS-- +Gabriel Caruso (carusogabriel34@gmail.com) +--FILE-- +<?php +var_dump(is_countable(new class extends ArrayIterator {})); +var_dump(is_countable((array) new stdClass())); +var_dump(is_countable(new class implements Countable { + public function count() + { + return count(1, 'foo'); + } +})); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/general_functions/is_countable_with_variables.phpt b/ext/standard/tests/general_functions/is_countable_with_variables.phpt new file mode 100644 index 0000000000..700077ef17 --- /dev/null +++ b/ext/standard/tests/general_functions/is_countable_with_variables.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test is_countable() function +--CREDITS-- +Gabriel Caruso (carusogabriel34@gmail.com) +--FILE-- +<?php +var_dump(is_countable([1, 2, 3])); +var_dump(is_countable((array) 1)); +var_dump(is_countable((object) ['foo', 'bar', 'baz'])); +var_dump(is_countable()); + +$foo = ['', []]; + +if (is_countable($foo)) { + var_dump(count($foo)); +} + +$bar = null; +if (!is_countable($bar)) { + count($bar); +} +?> +--EXPECTF-- +bool(true) +bool(true) +bool(false) + +Warning: is_countable() expects exactly 1 parameter, 0 given in %s on line %d +NULL +int(2) + +Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d diff --git a/ext/standard/type.c b/ext/standard/type.c index e0a00aedcb..fff5b4eabd 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -395,6 +395,20 @@ PHP_FUNCTION(is_iterable) } /* }}} */ +/* {{{ proto bool is_countable(mixed var) + Returns true if var is countable (array or instance of Countable). */ +PHP_FUNCTION(is_countable) +{ + zval *var; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(var) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL(zend_is_countable(var)); +} +/* }}} */ + /* * Local variables: * tab-width: 4 |