]> granicus.if.org Git - php/commitdiff
Implemented FR #62840 (Add sort flag to ArrayObject::ksort)
authorXinchen Hui <laruence@php.net>
Tue, 21 Aug 2012 05:32:15 +0000 (13:32 +0800)
committerXinchen Hui <laruence@php.net>
Tue, 21 Aug 2012 05:32:15 +0000 (13:32 +0800)
NEWS
ext/spl/spl_array.c
ext/spl/tests/arrayObject_asort_basic1.phpt
ext/spl/tests/arrayObject_ksort_basic1.phpt

diff --git a/NEWS b/NEWS
index 27a34c3c689948f5191c53b14d852bcab47509e5..d60f51b5305ff0799c89b54b981e1117bd5f41ef 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,9 @@ PHP                                                                        NEWS
   . Fixed bug (segfault due to PS(mod_user_implemented) not be reseted 
     when close handler call exit). (Laruence)
 
+- SPL:
+  . Implemented FR #62840 (Add sort flag to ArrayObject::ksort). (Laruence)
+
 - Standard:
   . Fixed bug #62836 (Seg fault or broken object references on unserialize()).
     (Laruence)
index e2ea17a3fe3f89f39f5939f1464422c2f80cc1fd..1e4577a3f961b07e24a47fb524b9186194e1e3f5 100755 (executable)
@@ -58,6 +58,10 @@ PHPAPI zend_class_entry  *spl_ce_RecursiveArrayIterator;
 #define SPL_ARRAY_INT_MASK           0xFFFF0000
 #define SPL_ARRAY_CLONE_MASK         0x0300FFFF
 
+#define SPL_ARRAY_METHOD_NO_ARG                                0
+#define SPL_ARRAY_METHOD_USE_ARG               1
+#define SPL_ARRAY_METHOD_MAY_USER_ARG          2
+
 typedef struct _spl_array_object {
        zend_object       std;
        zval              *array;
@@ -1426,26 +1430,36 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
 {
        spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
        HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
-       zval *tmp, *arg;
+       zval *tmp, *arg = NULL;
        zval *retval_ptr = NULL;
        
        MAKE_STD_ZVAL(tmp);
        Z_TYPE_P(tmp) = IS_ARRAY;
        Z_ARRVAL_P(tmp) = aht;
        
-       if (use_arg) {
-               if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
+       if (!use_arg) {
+               aht->nApplyCount++;
+               zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
+               aht->nApplyCount--;
+       } else if (use_arg == SPL_ARRAY_METHOD_MAY_USER_ARG) {
+               if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
                        Z_TYPE_P(tmp) = IS_NULL;
                        zval_ptr_dtor(&tmp);
-                       zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0 TSRMLS_CC);
+                       zend_throw_exception(spl_ce_BadMethodCallException, "Function expects one argument at most", 0 TSRMLS_CC);
                        return;
                }
                aht->nApplyCount++;
-               zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 2, tmp, arg TSRMLS_CC);
+               zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, arg? 2 : 1, tmp, arg TSRMLS_CC);
                aht->nApplyCount--;
        } else {
+               if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
+                       Z_TYPE_P(tmp) = IS_NULL;
+                       zval_ptr_dtor(&tmp);
+                       zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0 TSRMLS_CC);
+                       return;
+               }
                aht->nApplyCount++;
-               zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
+               zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 2, tmp, arg TSRMLS_CC);
                aht->nApplyCount--;
        }
        Z_TYPE_P(tmp) = IS_NULL; /* we want to destroy the zval, not the hashtable */
@@ -1461,35 +1475,35 @@ SPL_METHOD(cname, fname) \
        spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \
 }
 
-/* {{{ proto int ArrayObject::asort()
-       proto int ArrayIterator::asort()
+/* {{{ proto int ArrayObject::asort([int $sort_flags = SORT_REGULAR ])
+       proto int ArrayIterator::asort([int $sort_flags = SORT_REGULAR ])
    Sort the entries by values. */
-SPL_ARRAY_METHOD(Array, asort, 0) /* }}} */
+SPL_ARRAY_METHOD(Array, asort, SPL_ARRAY_METHOD_MAY_USER_ARG) /* }}} */
 
-/* {{{ proto int ArrayObject::ksort()
-       proto int ArrayIterator::ksort()
+/* {{{ proto int ArrayObject::ksort([int $sort_flags = SORT_REGULAR ])
+       proto int ArrayIterator::ksort([int $sort_flags = SORT_REGULAR ])
    Sort the entries by key. */
-SPL_ARRAY_METHOD(Array, ksort, 0) /* }}} */
+SPL_ARRAY_METHOD(Array, ksort, SPL_ARRAY_METHOD_MAY_USER_ARG) /* }}} */
 
 /* {{{ proto int ArrayObject::uasort(callback cmp_function)
        proto int ArrayIterator::uasort(callback cmp_function)
    Sort the entries by values user defined function. */
-SPL_ARRAY_METHOD(Array, uasort, 1) /* }}} */
+SPL_ARRAY_METHOD(Array, uasort, SPL_ARRAY_METHOD_USE_ARG) /* }}} */
 
 /* {{{ proto int ArrayObject::uksort(callback cmp_function)
        proto int ArrayIterator::uksort(callback cmp_function)
    Sort the entries by key using user defined function. */
-SPL_ARRAY_METHOD(Array, uksort, 1) /* }}} */
+SPL_ARRAY_METHOD(Array, uksort, SPL_ARRAY_METHOD_USE_ARG) /* }}} */
 
 /* {{{ proto int ArrayObject::natsort()
        proto int ArrayIterator::natsort()
    Sort the entries by values using "natural order" algorithm. */
-SPL_ARRAY_METHOD(Array, natsort, 0) /* }}} */
+SPL_ARRAY_METHOD(Array, natsort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */
 
 /* {{{ proto int ArrayObject::natcasesort()
        proto int ArrayIterator::natcasesort()
    Sort the entries by key using case insensitive "natural order" algorithm. */
-SPL_ARRAY_METHOD(Array, natcasesort, 0) /* }}} */
+SPL_ARRAY_METHOD(Array, natcasesort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */
 
 /* {{{ proto mixed|NULL ArrayIterator::current()
    Return current array entry */
index ec69049a32809e94461ebf37a57daa489e9e1b92..53df1d502b92479ae3b5ffb65e5273646735dc25 100644 (file)
@@ -17,12 +17,14 @@ var_dump($ao1->asort());
 var_dump($ao1);
 var_dump($ao2->asort('blah'));
 var_dump($ao2);
+var_dump($ao2->asort(SORT_NUMERIC));
+var_dump($ao2);
 ?>
 ===DONE===
 --EXPECTF--
 *** Testing ArrayObject::asort() : basic functionality ***
 bool(true)
-object(ArrayObject)#1 (1) {
+object(ArrayObject)#%d (1) {
   ["storage":"ArrayObject":private]=>
   array(3) {
     [1]=>
@@ -33,8 +35,22 @@ object(ArrayObject)#1 (1) {
     int(4)
   }
 }
+
+Warning: asort() expects parameter 2 to be long, string given in %sarrayObject_asort_basic1.php on line %d
+bool(false)
+object(ArrayObject)#%d (1) {
+  ["storage":"ArrayObject":private]=>
+  array(3) {
+    ["a"]=>
+    int(4)
+    ["b"]=>
+    int(2)
+    ["c"]=>
+    int(3)
+  }
+}
 bool(true)
-object(ArrayObject)#2 (1) {
+object(ArrayObject)#%d (1) {
   ["storage":"ArrayObject":private]=>
   array(3) {
     ["b"]=>
index 9c8d1e73451c4cb8592b4fd520f405bfb7c5dc21..8f379381269716c7b3ea3cbca41089ad24d88073 100644 (file)
@@ -16,12 +16,14 @@ var_dump($ao1->ksort());
 var_dump($ao1);
 var_dump($ao2->ksort('blah'));
 var_dump($ao2);
+var_dump($ao2->ksort(SORT_STRING));
+var_dump($ao2);
 ?>
 ===DONE===
 --EXPECTF--
 *** Testing ArrayObject::ksort() : basic functionality ***
 bool(true)
-object(ArrayObject)#1 (1) {
+object(ArrayObject)#%d (1) {
   ["storage":"ArrayObject":private]=>
   array(3) {
     [0]=>
@@ -32,18 +34,34 @@ object(ArrayObject)#1 (1) {
     int(3)
   }
 }
-bool(true)
+
+Warning: ksort() expects parameter 2 to be long, string given in %sarrayObject_ksort_basic1.php on line %d
+bool(false)
 object(ArrayObject)#2 (1) {
   ["storage":"ArrayObject":private]=>
   array(4) {
-    ["a"]=>
-    int(2)
     ["b"]=>
     int(4)
+    ["a"]=>
+    int(2)
     ["q"]=>
     int(3)
     [99]=>
     string(1) "x"
   }
 }
+bool(true)
+object(ArrayObject)#%d (1) {
+  ["storage":"ArrayObject":private]=>
+  array(4) {
+    [99]=>
+    string(1) "x"
+    ["a"]=>
+    int(2)
+    ["b"]=>
+    int(4)
+    ["q"]=>
+    int(3)
+  }
+}
 ===DONE===