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
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)

View File

@ -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,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);
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 (!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) {
Z_TYPE_P(tmp) = IS_NULL;
zval_ptr_dtor(&tmp);
@ -1443,10 +1461,6 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
aht->nApplyCount++;
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 2, tmp, arg TSRMLS_CC);
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 */
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); \
}
/* {{{ 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 */

View 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"]=>

View 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===