#include "php_ini.h"
#include "ext/standard/info.h"
#include "zend_interfaces.h"
+#include "zend_exceptions.h"
#include "php_spl.h"
#include "spl_functions.h"
zend_object std;
zval *array;
HashPosition pos;
+ int is_ref;
} spl_array_object;
/* {{{ spl_array_object_free_storage */
if (orig) {
intern->array = orig->array;
ZVAL_ADDREF(intern->array);
+ intern->is_ref = 1;
} else {
MAKE_STD_ZVAL(intern->array);
array_init(intern->array);
+ intern->is_ref = 0;
}
zend_hash_internal_pointer_reset_ex(HASH_OF(intern->array), &intern->pos);
spl_array_write_dimension(getThis(), index, value TSRMLS_CC);
} /* }}} */
-/* {{{ proto void ArrayObject::append(mixed $newval)
- proto void ArrayIterator::append(mixed $newval)
- Appends the value (cannot be called for objects). */
-SPL_METHOD(Array, append)
+
+void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC) /* {{{ */
{
- zval *object = getThis();
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
HashTable *aht = HASH_OF(intern->array);
- zval *value;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
- return;
- }
-
if (!aht) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and is no longer an array");
return;
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot append properties to objects, use %s::offsetSet() instead", Z_OBJCE_P(object)->name);
}
- spl_array_write_dimension(object, NULL, value TSRMLS_CC);
+ spl_array_write_dimension(object, NULL, append_value TSRMLS_CC);
if (!intern->pos) {
intern->pos = aht->pListTail;
}
} /* }}} */
+/* {{{ proto void ArrayObject::append(mixed $newval)
+ proto void ArrayIterator::append(mixed $newval)
+ Appends the value (cannot be called for objects). */
+SPL_METHOD(Array, append)
+{
+ zval *value;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+ return;
+ }
+ spl_array_iterator_append(getThis(), value TSRMLS_CC);
+} /* }}} */
+
/* {{{ proto void ArrayObject::offsetUnset(mixed $index)
proto void ArrayIterator::offsetUnset(mixed $index)
Unsets the value at the specified $index. */
{
HashTable *aht = HASH_OF(intern->array);
- zend_hash_move_forward_ex(aht, &intern->pos);
- if (Z_TYPE_P(intern->array) == IS_OBJECT) {
- return spl_array_skip_protected(intern TSRMLS_CC);
+ if (intern->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and internal position is no longer valid");
+ return FAILURE;
} else {
- return zend_hash_has_more_elements_ex(aht, &intern->pos);
+ zend_hash_move_forward_ex(aht, &intern->pos);
+ if (Z_TYPE_P(intern->array) == IS_OBJECT) {
+ return spl_array_skip_protected(intern TSRMLS_CC);
+ } else {
+ return zend_hash_has_more_elements_ex(aht, &intern->pos);
+ }
}
} /* }}} */
return FAILURE;
}
- if (object->pos && object->array->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
+ if (object->pos && object->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::valid(): Array was modified outside object and internal position is no longer valid");
return FAILURE;
} else {
return HASH_KEY_NON_EXISTANT;
}
- if (object->array->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
+ if (object->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and internal position is no longer valid");
return HASH_KEY_NON_EXISTANT;
}
return;
}
- if (object->array->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
+ if (object->is_ref && spl_hash_verify_pos(object TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::next(): Array was modified outside object and internal position is no longer valid");
} else {
spl_array_next(object TSRMLS_CC);
if (ZEND_NUM_ARGS() == 0) {
return; /* nothing to do */
}
-/* exceptions do not work yet
- php_set_error_handling(EH_THROW, zend_exception_get_default() TSRMLS_CC);*/
+ php_set_error_handling(EH_THROW, zend_exception_get_default() TSRMLS_CC);
intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
intern->array = other->array;
} else {
if (!HASH_OF(*array)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object, using empty array instead");
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
+ zend_throw_exception(zend_exception_get_default(), "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
return;
}
zval_dtor(intern->array);
return;
}
- if (intern->array->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
+ if (intern->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and internal position is no longer valid");
return;
}
return;
}
- if (intern->array->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
+ if (intern->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and internal position is no longer valid");
return;
}
return;
}
- if (intern->array->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and internal position is no longer valid");
- } else {
- spl_array_next(intern TSRMLS_CC);
- }
+ spl_array_next(intern TSRMLS_CC);
}
/* }}} */
return;
}
- if (intern->pos && intern->array->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
+ if (intern->pos && intern->is_ref && spl_hash_verify_pos(intern TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and internal position is no longer valid");
RETURN_FALSE;
} else {