summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2014-04-14 00:08:36 +0200
committerBob Weinand <bobwei9@hotmail.com>2014-04-14 00:08:36 +0200
commita93e734f8143815bcb4f675567146d4326c05fb9 (patch)
treebc4024839e77db0f21c028b5aa955e862620dc63
parent0e023e978445a7d2f723cabfd4a59d65886be72a (diff)
parentbf3edbada68cb99f4c67f60fe113a6cf0b44e0fa (diff)
downloadphp-git-a93e734f8143815bcb4f675567146d4326c05fb9.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
-rw-r--r--NEWS2
-rw-r--r--UPGRADING.INTERNALS7
-rw-r--r--ext/phar/phar_object.c6
-rw-r--r--ext/spl/spl_observer.c23
-rw-r--r--ext/standard/array.c9
-rw-r--r--ext/standard/php_array.h4
6 files changed, 41 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index cd75dca28f..e4809ae403 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP NEWS
. Fixed bug #66568 (Update reflection information for unserialize() function).
(Ferenc)
. Fixed bug #66660 (Composer.phar install/update fails). (Ferenc)
+ . Fixed bug #67064 (Countable interface prevents using 2nd parameter
+ ($mode) of count() function). (Bob)
- mysqlnd:
. Added a new fetching mode to mysqlnd. (Andrey)
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index f3e7281ca1..1bc359bfd0 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -182,6 +182,13 @@ UPGRADE NOTES - PHP X.Y
IAP of ht (for compatibility with the previous implementation) and resets
CVs if the passed hashtable is the global symbol table.
+ j. An additional parameter is sent to Countable::count()
+
+ That parameter denotes the $mode passed to count; it shouldn't affect any
+ userland code, but any zend_parse_parameters() used with no arguments should
+ fail. Extensions which implement Countable internally, need to accept one
+ optional long as parameter.
+
========================
2. Build system changes
========================
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 99907f86dd..407edda0fb 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1934,10 +1934,12 @@ PHP_METHOD(Phar, buildFromIterator)
*/
PHP_METHOD(Phar, count)
{
+ /* mode can be ignored, maximum depth is 1 */
+ long mode;
PHAR_ARCHIVE_OBJECT();
- if (zend_parse_parameters_none() == FAILURE) {
- return;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) {
+ RETURN_FALSE;
}
RETURN_LONG(zend_hash_num_elements(&phar_obj->arc.archive->manifest));
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index 1a706f7642..91830ab000 100644
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -26,6 +26,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+#include "ext/standard/php_array.h"
#include "ext/standard/php_var.h"
#include "ext/standard/php_smart_str.h"
#include "zend_interfaces.h"
@@ -621,11 +622,27 @@ SPL_METHOD(SplObjectStorage, contains)
SPL_METHOD(SplObjectStorage, count)
{
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
-
- if (zend_parse_parameters_none() == FAILURE) {
+ long mode = COUNT_NORMAL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) {
return;
}
-
+
+ if (mode == COUNT_RECURSIVE) {
+ long ret = zend_hash_num_elements(&intern->storage);
+ HashPosition position;
+ zval *element;
+
+ for (zend_hash_internal_pointer_reset_ex(&intern->storage, &position);
+ zend_hash_get_current_data_ex(&intern->storage, (void**) &element, &position) == SUCCESS;
+ zend_hash_move_forward_ex(&intern->storage, &position)) {
+ ret += php_count_recursive(element, mode TSRMLS_CC);
+ }
+
+ RETURN_LONG(ret);
+ return;
+ }
+
RETURN_LONG(zend_hash_num_elements(&intern->storage));
} /* }}} */
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 34057e34c8..4f98331035 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -64,9 +64,6 @@
#define CASE_LOWER 0
#define CASE_UPPER 1
-#define COUNT_NORMAL 0
-#define COUNT_RECURSIVE 1
-
#define DIFF_NORMAL 1
#define DIFF_KEY 2
#define DIFF_ASSOC 6
@@ -274,7 +271,7 @@ PHP_FUNCTION(ksort)
}
/* }}} */
-static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
+PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
{
long cnt = 0;
zval **element;
@@ -338,13 +335,15 @@ PHP_FUNCTION(count)
if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
zval *mode_zv;
MAKE_STD_ZVAL(mode_zv);
- Z_LVAL_P(mode_zv) = mode;
+ ZVAL_LONG(mode_zv, mode);
zend_call_method_with_1_params(&array, NULL, NULL, "count", &retval, mode_zv);
if (retval) {
convert_to_long_ex(&retval);
RETVAL_LONG(Z_LVAL_P(retval));
zval_ptr_dtor(&retval);
}
+ zval_dtor(mode_zv);
+ efree(mode_zv);
return;
}
#endif
diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h
index deddeb4871..1b30e34787 100644
--- a/ext/standard/php_array.h
+++ b/ext/standard/php_array.h
@@ -107,6 +107,7 @@ PHPAPI void php_splice(HashTable *ht, zend_uint offset, zend_uint length, zval *
PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);
PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC);
PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
+PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC);
#define PHP_SORT_REGULAR 0
#define PHP_SORT_NUMERIC 1
@@ -117,6 +118,9 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
#define PHP_SORT_NATURAL 6
#define PHP_SORT_FLAG_CASE 8
+#define COUNT_NORMAL 0
+#define COUNT_RECURSIVE 1
+
#define ARRAY_FILTER_USE_BOTH 1
#define ARRAY_FILTER_USE_KEY 2