Skip to content

Commit 9afb3e0

Browse files
committed
- Update after api changes
- MFH . ArrayIterator/ArrayObject: function lookup caches and array functions . Added RegExIterator, RecursiveRegExIterator . Added (full) caching support for CachingIterator
1 parent 77c1b56 commit 9afb3e0

File tree

5 files changed

+588
-86
lines changed

5 files changed

+588
-86
lines changed

ext/spl/spl_array.c

+201-67
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ PHPAPI zend_class_entry *spl_ce_Countable;
4646

4747
#define SPL_ARRAY_STD_PROP_LIST 0x00000001
4848
#define SPL_ARRAY_ARRAY_AS_PROPS 0x00000002
49+
#define SPL_ARRAY_OVERLOADED_REWIND 0x00010000
50+
#define SPL_ARRAY_OVERLOADED_VALID 0x00020000
51+
#define SPL_ARRAY_OVERLOADED_KEY 0x00040000
52+
#define SPL_ARRAY_OVERLOADED_CURRENT 0x00080000
53+
#define SPL_ARRAY_OVERLOADED_NEXT 0x00100000
4954
#define SPL_ARRAY_IS_REF 0x01000000
5055
#define SPL_ARRAY_IS_SELF 0x02000000
5156
#define SPL_ARRAY_USE_OTHER 0x04000000
52-
#define SPL_ARRAY_INT_MASK 0xFF000000
57+
#define SPL_ARRAY_INT_MASK 0xFFFF0000
5358
#define SPL_ARRAY_CLONE_MASK 0x03000007
5459

5560
typedef struct _spl_array_object {
@@ -114,7 +119,7 @@ static void spl_array_object_free_storage(void *object TSRMLS_DC)
114119
}
115120
/* }}} */
116121

117-
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC);
122+
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
118123

119124
/* {{{ spl_array_object_new */
120125
static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, spl_array_object **obj, zval *orig, int clone_orig TSRMLS_DC)
@@ -166,6 +171,7 @@ static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, s
166171
while (parent) {
167172
if (parent == spl_ce_ArrayIterator || parent == spl_ce_RecursiveArrayIterator) {
168173
retval.handlers = &spl_handler_ArrayIterator;
174+
class_type->get_iterator = spl_array_get_iterator;
169175
break;
170176
} else if (parent == spl_ce_ArrayObject) {
171177
retval.handlers = &spl_handler_ArrayObject;
@@ -195,7 +201,25 @@ static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, s
195201
intern->fptr_offset_del = NULL;
196202
}
197203
}
198-
intern->ce_get_iterator = spl_ce_ArrayIterator;
204+
/* Cache iterator functions if ArrayIterator or derived. Check current's */
205+
/* cache since only current is always required */
206+
if (retval.handlers == &spl_handler_ArrayIterator) {
207+
if (!class_type->iterator_funcs.zf_current) {
208+
zend_hash_find(&class_type->function_table, "rewind", sizeof("rewind"), (void **) &class_type->iterator_funcs.zf_rewind);
209+
zend_hash_find(&class_type->function_table, "valid", sizeof("valid"), (void **) &class_type->iterator_funcs.zf_valid);
210+
zend_hash_find(&class_type->function_table, "key", sizeof("key"), (void **) &class_type->iterator_funcs.zf_key);
211+
zend_hash_find(&class_type->function_table, "current", sizeof("current"), (void **) &class_type->iterator_funcs.zf_current);
212+
zend_hash_find(&class_type->function_table, "next", sizeof("next"), (void **) &class_type->iterator_funcs.zf_next);
213+
}
214+
if (inherited) {
215+
if (class_type->iterator_funcs.zf_rewind->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_REWIND;
216+
if (class_type->iterator_funcs.zf_valid->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_VALID;
217+
if (class_type->iterator_funcs.zf_key->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_KEY;
218+
if (class_type->iterator_funcs.zf_current->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_CURRENT;
219+
if (class_type->iterator_funcs.zf_next->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_NEXT;
220+
}
221+
}
222+
199223
zend_hash_internal_pointer_reset_ex(spl_array_get_hash_table(intern, 0 TSRMLS_CC), &intern->pos);
200224
return retval;
201225
}
@@ -659,15 +683,16 @@ static int spl_array_next(spl_array_object *intern TSRMLS_DC) /* {{{ */
659683

660684
/* define an overloaded iterator structure */
661685
typedef struct {
662-
zend_object_iterator intern;
686+
zend_user_iterator intern;
663687
spl_array_object *object;
664688
} spl_array_it;
665689

666690
static void spl_array_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
667691
{
668692
spl_array_it *iterator = (spl_array_it *)iter;
669693

670-
zval_ptr_dtor((zval**)&iterator->intern.data);
694+
zend_user_it_invalidate_current(iter TSRMLS_CC);
695+
zval_ptr_dtor((zval**)&iterator->intern.it.data);
671696

672697
efree(iterator);
673698
}
@@ -679,16 +704,20 @@ static int spl_array_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
679704
spl_array_object *object = iterator->object;
680705
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
681706

682-
if (!aht) {
683-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::valid(): Array was modified outside object and is no longer an array");
684-
return FAILURE;
685-
}
686-
687-
if (object->pos && (object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
688-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::valid(): Array was modified outside object and internal position is no longer valid");
689-
return FAILURE;
707+
if (object->ar_flags & SPL_ARRAY_OVERLOADED_VALID) {
708+
return zend_user_it_valid(iter TSRMLS_CC);
690709
} else {
691-
return zend_hash_has_more_elements_ex(aht, &object->pos);
710+
if (!aht) {
711+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::valid(): Array was modified outside object and is no longer an array");
712+
return FAILURE;
713+
}
714+
715+
if (object->pos && (object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
716+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::valid(): Array was modified outside object and internal position is no longer valid");
717+
return FAILURE;
718+
} else {
719+
return zend_hash_has_more_elements_ex(aht, &object->pos);
720+
}
692721
}
693722
}
694723
/* }}} */
@@ -698,9 +727,13 @@ static void spl_array_it_get_current_data(zend_object_iterator *iter, zval ***da
698727
spl_array_it *iterator = (spl_array_it *)iter;
699728
spl_array_object *object = iterator->object;
700729
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
701-
702-
if (zend_hash_get_current_data_ex(aht, (void**)data, &object->pos) == FAILURE) {
703-
*data = NULL;
730+
731+
if (object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT) {
732+
zend_user_it_get_current_data(iter, data TSRMLS_CC);
733+
} else {
734+
if (zend_hash_get_current_data_ex(aht, (void**)data, &object->pos) == FAILURE) {
735+
*data = NULL;
736+
}
704737
}
705738
}
706739
/* }}} */
@@ -711,17 +744,21 @@ static int spl_array_it_get_current_key(zend_object_iterator *iter, char **str_k
711744
spl_array_object *object = iterator->object;
712745
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
713746

714-
if (!aht) {
715-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array");
716-
return HASH_KEY_NON_EXISTANT;
717-
}
718-
719-
if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
720-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and internal position is no longer valid");
721-
return HASH_KEY_NON_EXISTANT;
747+
if (object->ar_flags & SPL_ARRAY_OVERLOADED_KEY) {
748+
return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
749+
} else {
750+
if (!aht) {
751+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array");
752+
return HASH_KEY_NON_EXISTANT;
753+
}
754+
755+
if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
756+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and internal position is no longer valid");
757+
return HASH_KEY_NON_EXISTANT;
758+
}
759+
760+
return zend_hash_get_current_key_ex(aht, str_key, str_key_len, int_key, 1, &object->pos);
722761
}
723-
724-
return zend_hash_get_current_key_ex(aht, str_key, str_key_len, int_key, 1, &object->pos);
725762
}
726763
/* }}} */
727764

@@ -731,15 +768,20 @@ static void spl_array_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {
731768
spl_array_object *object = iterator->object;
732769
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
733770

734-
if (!aht) {
735-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array");
736-
return;
737-
}
738-
739-
if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
740-
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::next(): Array was modified outside object and internal position is no longer valid");
771+
if (object->ar_flags & SPL_ARRAY_OVERLOADED_NEXT) {
772+
zend_user_it_move_forward(iter TSRMLS_CC);
741773
} else {
742-
spl_array_next(object TSRMLS_CC);
774+
zend_user_it_invalidate_current(iter TSRMLS_CC);
775+
if (!aht) {
776+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array");
777+
return;
778+
}
779+
780+
if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
781+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::next(): Array was modified outside object and internal position is no longer valid");
782+
} else {
783+
spl_array_next(object TSRMLS_CC);
784+
}
743785
}
744786
}
745787
/* }}} */
@@ -763,7 +805,12 @@ static void spl_array_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
763805
spl_array_it *iterator = (spl_array_it *)iter;
764806
spl_array_object *object = iterator->object;
765807

766-
spl_array_rewind(object TSRMLS_CC);
808+
if (object->ar_flags & SPL_ARRAY_OVERLOADED_REWIND) {
809+
zend_user_it_rewind(iter TSRMLS_CC);
810+
} else {
811+
zend_user_it_invalidate_current(iter TSRMLS_CC);
812+
spl_array_rewind(object TSRMLS_CC);
813+
}
767814
}
768815
/* }}} */
769816

@@ -777,14 +824,22 @@ zend_object_iterator_funcs spl_array_it_funcs = {
777824
spl_array_it_rewind
778825
};
779826

780-
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) /* {{{ */
827+
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
781828
{
782-
spl_array_it *iterator = emalloc(sizeof(spl_array_it));
829+
spl_array_it *iterator;
783830
spl_array_object *array_object = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
784831

832+
if (by_ref && (array_object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT)) {
833+
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
834+
}
835+
836+
iterator = emalloc(sizeof(spl_array_it));
837+
785838
object->refcount++;
786-
iterator->intern.data = (void*)object;
787-
iterator->intern.funcs = &spl_array_it_funcs;
839+
iterator->intern.it.data = (void*)object;
840+
iterator->intern.it.funcs = &spl_array_it_funcs;
841+
iterator->intern.ce = ce;
842+
iterator->intern.value = NULL;
788843
iterator->object = array_object;
789844

790845
return (zend_object_iterator*)iterator;
@@ -1077,6 +1132,63 @@ SPL_METHOD(Array, count)
10771132
RETURN_LONG(count);
10781133
} /* }}} */
10791134

1135+
static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fname_len, int use_arg)
1136+
{
1137+
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1138+
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
1139+
zval tmp, *arg;
1140+
1141+
INIT_PZVAL(&tmp);
1142+
Z_TYPE(tmp) = IS_ARRAY;
1143+
Z_ARRVAL(tmp) = aht;
1144+
1145+
if (use_arg) {
1146+
if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
1147+
zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0 TSRMLS_CC);
1148+
return;
1149+
}
1150+
zend_call_method(NULL, NULL, NULL, fname, fname_len, &return_value, 2, &tmp, arg TSRMLS_CC);
1151+
} else {
1152+
zend_call_method(NULL, NULL, NULL, fname, fname_len, &return_value, 1, &tmp, NULL TSRMLS_CC);
1153+
}
1154+
}
1155+
1156+
#define SPL_ARRAY_METHOD(cname, fname, use_arg) \
1157+
SPL_METHOD(cname, fname) \
1158+
{ \
1159+
spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \
1160+
}
1161+
1162+
/* {{{ proto int ArrayObject::asort()
1163+
proto int ArrayIterator::asort()
1164+
Sort the entries by values. */
1165+
SPL_ARRAY_METHOD(Array, asort, 0)
1166+
1167+
/* {{{ proto int ArrayObject::ksort()
1168+
proto int ArrayIterator::ksort()
1169+
Sort the entries by key. */
1170+
SPL_ARRAY_METHOD(Array, ksort, 0)
1171+
1172+
/* {{{ proto int ArrayObject::uasort(callback cmp_function)
1173+
proto int ArrayIterator::uasort(callback cmp_function)
1174+
Sort the entries by values user defined function. */
1175+
SPL_ARRAY_METHOD(Array, uasort, 1)
1176+
1177+
/* {{{ proto int ArrayObject::uksort(callback cmp_function)
1178+
proto int ArrayIterator::uksort(callback cmp_function)
1179+
Sort the entries by key using user defined function. */
1180+
SPL_ARRAY_METHOD(Array, uksort, 1)
1181+
1182+
/* {{{ proto int ArrayObject::natsort()
1183+
proto int ArrayIterator::natsort()
1184+
Sort the entries by values using "natural order" algorithm. */
1185+
SPL_ARRAY_METHOD(Array, natsort, 0)
1186+
1187+
/* {{{ proto int ArrayObject::natcasesort()
1188+
proto int ArrayIterator::natcasesort()
1189+
Sort the entries by key using case insensitive "natural order" algorithm. */
1190+
SPL_ARRAY_METHOD(Array, natcasesort, 0)
1191+
10801192
/* {{{ proto mixed|NULL ArrayIterator::current()
10811193
Return current array entry */
10821194
SPL_METHOD(Array, current)
@@ -1107,7 +1219,11 @@ SPL_METHOD(Array, current)
11071219
Return current array key */
11081220
SPL_METHOD(Array, key)
11091221
{
1110-
zval *object = getThis();
1222+
spl_array_iterator_key(getThis(), return_value TSRMLS_CC);
1223+
}
1224+
1225+
void spl_array_iterator_key(zval *object, zval *return_value TSRMLS_DC) /* {{{ */
1226+
{
11111227
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
11121228
char *string_key;
11131229
uint string_length;
@@ -1273,17 +1389,28 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_setIteratorClass, 0)
12731389
ZEND_ARG_INFO(0, iteratorClass)
12741390
ZEND_END_ARG_INFO()
12751391

1392+
static
1393+
ZEND_BEGIN_ARG_INFO(arginfo_array_uXsort, 0)
1394+
ZEND_ARG_INFO(0, cmp_function )
1395+
ZEND_END_ARG_INFO();
1396+
12761397
static zend_function_entry spl_funcs_ArrayObject[] = {
1277-
SPL_ME(Array, __construct, arginfo_array___construct, ZEND_ACC_PUBLIC)
1278-
SPL_ME(Array, offsetExists, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1279-
SPL_ME(Array, offsetGet, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1280-
SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC)
1281-
SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1282-
SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC)
1283-
SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC)
1284-
SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC)
1285-
SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC)
1286-
SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC)
1398+
SPL_ME(Array, __construct, arginfo_array___construct, ZEND_ACC_PUBLIC)
1399+
SPL_ME(Array, offsetExists, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1400+
SPL_ME(Array, offsetGet, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1401+
SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC)
1402+
SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1403+
SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC)
1404+
SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC)
1405+
SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC)
1406+
SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC)
1407+
SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC)
1408+
SPL_ME(Array, asort, NULL, ZEND_ACC_PUBLIC)
1409+
SPL_ME(Array, ksort, NULL, ZEND_ACC_PUBLIC)
1410+
SPL_ME(Array, uasort, arginfo_array_uXsort, ZEND_ACC_PUBLIC)
1411+
SPL_ME(Array, uksort, arginfo_array_uXsort, ZEND_ACC_PUBLIC)
1412+
SPL_ME(Array, natsort, NULL, ZEND_ACC_PUBLIC)
1413+
SPL_ME(Array, natcasesort, NULL, ZEND_ACC_PUBLIC)
12871414
/* ArrayObject specific */
12881415
SPL_ME(Array, getIterator, NULL, ZEND_ACC_PUBLIC)
12891416
SPL_ME(Array, exchangeArray, arginfo_array_exchangeArray, ZEND_ACC_PUBLIC)
@@ -1293,23 +1420,29 @@ static zend_function_entry spl_funcs_ArrayObject[] = {
12931420
};
12941421

12951422
static zend_function_entry spl_funcs_ArrayIterator[] = {
1296-
SPL_ME(Array, __construct, arginfo_array___construct, ZEND_ACC_PUBLIC)
1297-
SPL_ME(Array, offsetExists, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1298-
SPL_ME(Array, offsetGet, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1299-
SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC)
1300-
SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1301-
SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC)
1302-
SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC)
1303-
SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC)
1304-
SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC)
1305-
SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC)
1423+
SPL_ME(Array, __construct, arginfo_array___construct, ZEND_ACC_PUBLIC)
1424+
SPL_ME(Array, offsetExists, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1425+
SPL_ME(Array, offsetGet, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1426+
SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC)
1427+
SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC)
1428+
SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC)
1429+
SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC)
1430+
SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC)
1431+
SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC)
1432+
SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC)
1433+
SPL_ME(Array, asort, NULL, ZEND_ACC_PUBLIC)
1434+
SPL_ME(Array, ksort, NULL, ZEND_ACC_PUBLIC)
1435+
SPL_ME(Array, uasort, arginfo_array_uXsort, ZEND_ACC_PUBLIC)
1436+
SPL_ME(Array, uksort, arginfo_array_uXsort, ZEND_ACC_PUBLIC)
1437+
SPL_ME(Array, natsort, NULL, ZEND_ACC_PUBLIC)
1438+
SPL_ME(Array, natcasesort, NULL, ZEND_ACC_PUBLIC)
13061439
/* ArrayIterator specific */
1307-
SPL_ME(Array, rewind, NULL, ZEND_ACC_PUBLIC)
1308-
SPL_ME(Array, current, NULL, ZEND_ACC_PUBLIC)
1309-
SPL_ME(Array, key, NULL, ZEND_ACC_PUBLIC)
1310-
SPL_ME(Array, next, NULL, ZEND_ACC_PUBLIC)
1311-
SPL_ME(Array, valid, NULL, ZEND_ACC_PUBLIC)
1312-
SPL_ME(Array, seek, arginfo_array_seek, ZEND_ACC_PUBLIC)
1440+
SPL_ME(Array, rewind, NULL, ZEND_ACC_PUBLIC)
1441+
SPL_ME(Array, current, NULL, ZEND_ACC_PUBLIC)
1442+
SPL_ME(Array, key, NULL, ZEND_ACC_PUBLIC)
1443+
SPL_ME(Array, next, NULL, ZEND_ACC_PUBLIC)
1444+
SPL_ME(Array, valid, NULL, ZEND_ACC_PUBLIC)
1445+
SPL_ME(Array, seek, arginfo_array_seek, ZEND_ACC_PUBLIC)
13131446
{NULL, NULL, NULL}
13141447
};
13151448

@@ -1355,6 +1488,7 @@ PHP_MINIT_FUNCTION(spl_array)
13551488

13561489
REGISTER_SPL_SUB_CLASS_EX(RecursiveArrayIterator, ArrayIterator, spl_array_object_new, spl_funcs_RecursiveArrayIterator);
13571490
REGISTER_SPL_IMPLEMENTS(RecursiveArrayIterator, RecursiveIterator);
1491+
spl_ce_RecursiveArrayIterator->get_iterator = spl_array_get_iterator;
13581492

13591493
REGISTER_SPL_INTERFACE(Countable);
13601494

0 commit comments

Comments
 (0)