Implemented FR #62840 (Add sort flag to ArrayObject::ksort)

This commit is contained in:
Xinchen Hui 2012-08-21 13:32:15 +08:00
parent c54d73d54c
commit 8722173ad5
4 changed files with 73 additions and 22 deletions

3
NEWS
View File

@ -38,6 +38,9 @@ PHP NEWS
. Fixed bug (segfault due to PS(mod_user_implemented) not be reseted . Fixed bug (segfault due to PS(mod_user_implemented) not be reseted
when close handler call exit). (Laruence) when close handler call exit). (Laruence)
- SPL:
. Implemented FR #62840 (Add sort flag to ArrayObject::ksort). (Laruence)
- Standard: - Standard:
. Fixed bug #62836 (Seg fault or broken object references on unserialize()). . Fixed bug #62836 (Seg fault or broken object references on unserialize()).
(Laruence) (Laruence)

View File

@ -58,6 +58,10 @@ PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator;
#define SPL_ARRAY_INT_MASK 0xFFFF0000 #define SPL_ARRAY_INT_MASK 0xFFFF0000
#define SPL_ARRAY_CLONE_MASK 0x0300FFFF #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 { typedef struct _spl_array_object {
zend_object std; zend_object std;
zval *array; zval *array;
@ -1426,14 +1430,28 @@ 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); 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); HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
zval *tmp, *arg; zval *tmp, *arg = NULL;
zval *retval_ptr = NULL; zval *retval_ptr = NULL;
MAKE_STD_ZVAL(tmp); MAKE_STD_ZVAL(tmp);
Z_TYPE_P(tmp) = IS_ARRAY; Z_TYPE_P(tmp) = IS_ARRAY;
Z_ARRVAL_P(tmp) = aht; Z_ARRVAL_P(tmp) = aht;
if (use_arg) { 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 one argument at most", 0 TSRMLS_CC);
return;
}
aht->nApplyCount++;
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) { 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; Z_TYPE_P(tmp) = IS_NULL;
zval_ptr_dtor(&tmp); zval_ptr_dtor(&tmp);
@ -1443,10 +1461,6 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
aht->nApplyCount++; 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, 2, tmp, arg TSRMLS_CC);
aht->nApplyCount--; aht->nApplyCount--;
} else {
aht->nApplyCount++;
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
aht->nApplyCount--;
} }
Z_TYPE_P(tmp) = IS_NULL; /* we want to destroy the zval, not the hashtable */ Z_TYPE_P(tmp) = IS_NULL; /* we want to destroy the zval, not the hashtable */
zval_ptr_dtor(&tmp); zval_ptr_dtor(&tmp);
@ -1461,35 +1475,35 @@ SPL_METHOD(cname, fname) \
spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \ spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \
} }
/* {{{ proto int ArrayObject::asort() /* {{{ proto int ArrayObject::asort([int $sort_flags = SORT_REGULAR ])
proto int ArrayIterator::asort() proto int ArrayIterator::asort([int $sort_flags = SORT_REGULAR ])
Sort the entries by values. */ 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 ArrayObject::ksort([int $sort_flags = SORT_REGULAR ])
proto int ArrayIterator::ksort() proto int ArrayIterator::ksort([int $sort_flags = SORT_REGULAR ])
Sort the entries by key. */ 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 ArrayObject::uasort(callback cmp_function)
proto int ArrayIterator::uasort(callback cmp_function) proto int ArrayIterator::uasort(callback cmp_function)
Sort the entries by values user defined 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 ArrayObject::uksort(callback cmp_function)
proto int ArrayIterator::uksort(callback cmp_function) proto int ArrayIterator::uksort(callback cmp_function)
Sort the entries by key using user defined 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 ArrayObject::natsort()
proto int ArrayIterator::natsort() proto int ArrayIterator::natsort()
Sort the entries by values using "natural order" algorithm. */ 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 ArrayObject::natcasesort()
proto int ArrayIterator::natcasesort() proto int ArrayIterator::natcasesort()
Sort the entries by key using case insensitive "natural order" algorithm. */ 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() /* {{{ proto mixed|NULL ArrayIterator::current()
Return current array entry */ Return current array entry */

View File

@ -17,12 +17,14 @@ var_dump($ao1->asort());
var_dump($ao1); var_dump($ao1);
var_dump($ao2->asort('blah')); var_dump($ao2->asort('blah'));
var_dump($ao2); var_dump($ao2);
var_dump($ao2->asort(SORT_NUMERIC));
var_dump($ao2);
?> ?>
===DONE=== ===DONE===
--EXPECTF-- --EXPECTF--
*** Testing ArrayObject::asort() : basic functionality *** *** Testing ArrayObject::asort() : basic functionality ***
bool(true) bool(true)
object(ArrayObject)#1 (1) { object(ArrayObject)#%d (1) {
["storage":"ArrayObject":private]=> ["storage":"ArrayObject":private]=>
array(3) { array(3) {
[1]=> [1]=>
@ -33,8 +35,22 @@ object(ArrayObject)#1 (1) {
int(4) 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) bool(true)
object(ArrayObject)#2 (1) { object(ArrayObject)#%d (1) {
["storage":"ArrayObject":private]=> ["storage":"ArrayObject":private]=>
array(3) { array(3) {
["b"]=> ["b"]=>

View File

@ -16,12 +16,14 @@ var_dump($ao1->ksort());
var_dump($ao1); var_dump($ao1);
var_dump($ao2->ksort('blah')); var_dump($ao2->ksort('blah'));
var_dump($ao2); var_dump($ao2);
var_dump($ao2->ksort(SORT_STRING));
var_dump($ao2);
?> ?>
===DONE=== ===DONE===
--EXPECTF-- --EXPECTF--
*** Testing ArrayObject::ksort() : basic functionality *** *** Testing ArrayObject::ksort() : basic functionality ***
bool(true) bool(true)
object(ArrayObject)#1 (1) { object(ArrayObject)#%d (1) {
["storage":"ArrayObject":private]=> ["storage":"ArrayObject":private]=>
array(3) { array(3) {
[0]=> [0]=>
@ -32,18 +34,34 @@ object(ArrayObject)#1 (1) {
int(3) 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) { object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=> ["storage":"ArrayObject":private]=>
array(4) { array(4) {
["a"]=>
int(2)
["b"]=> ["b"]=>
int(4) int(4)
["a"]=>
int(2)
["q"]=> ["q"]=>
int(3) int(3)
[99]=> [99]=>
string(1) "x" 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=== ===DONE===