helly Mon Nov 24 15:57:55 2003 EDT
Added files:
/php-src/tests/classes array_access_001.phpt array_access_002.phpt
array_access_003.phpt array_access_004.phpt
Modified files:
/ZendEngine2 zend_execute.c zend_interfaces.c zend_interfaces.h
zend_operators.c zend_operators.h
zend_object_handlers.c
Log:
Add new interface ArrayAccess to use objects as Arrays
Index: ZendEngine2/zend_execute.c
diff -u ZendEngine2/zend_execute.c:1.552 ZendEngine2/zend_execute.c:1.553
--- ZendEngine2/zend_execute.c:1.552 Mon Nov 24 13:13:29 2003
+++ ZendEngine2/zend_execute.c Mon Nov 24 15:57:53 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_execute.c,v 1.552 2003/11/24 18:13:29 andi Exp $ */
+/* $Id: zend_execute.c,v 1.553 2003/11/24 20:57:53 helly Exp $ */
#define ZEND_INTENSIVE_DEBUGGING 0
@@ -920,13 +920,17 @@
}
break;
case IS_OBJECT:
- if (type == BP_VAR_R) {
+ if (type == BP_VAR_R || type == BP_VAR_RW) {
if (!Z_OBJ_HT_P(container)->read_dimension) {
zend_error(E_ERROR, "Cannot use object as
array");
} else {
zval *dim = get_zval_ptr(op2, Ts,
&EG(free_op2), BP_VAR_R);
zval *overloaded_result =
Z_OBJ_HT_P(container)->read_dimension(container, dim TSRMLS_CC);
+ if (type == BP_VAR_RW &&
!overloaded_result->is_ref) {
+ zend_error(E_ERROR, "Objects used as
arrays in post/pre increment/decrement must return values by reference");
+ }
+
*retval = &overloaded_result;
AI_USE_PTR(T(result->u.var).var);
FREE_OP(Ts, op2, EG(free_op2));
Index: ZendEngine2/zend_interfaces.c
diff -u ZendEngine2/zend_interfaces.c:1.8 ZendEngine2/zend_interfaces.c:1.9
--- ZendEngine2/zend_interfaces.c:1.8 Mon Nov 17 19:18:48 2003
+++ ZendEngine2/zend_interfaces.c Mon Nov 24 15:57:53 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_interfaces.c,v 1.8 2003/11/18 00:18:48 helly Exp $ */
+/* $Id: zend_interfaces.c,v 1.9 2003/11/24 20:57:53 helly Exp $ */
#include "zend.h"
#include "zend_API.h"
@@ -25,6 +25,7 @@
zend_class_entry *zend_ce_traversable;
zend_class_entry *zend_ce_aggregate;
zend_class_entry *zend_ce_iterator;
+zend_class_entry *zend_ce_arrayaccess;
/* {{{ zend_call_method
Only returns the returned zval if retval_ptr != NULL */
@@ -344,6 +345,13 @@
}
/* }}} */
+/* {{{ zend_implement_arrayaccess */
+static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry
*class_type TSRMLS_DC)
+{
+ return SUCCESS;
+}
+/* }}}*/
+
/* {{{ function tables */
zend_function_entry zend_funcs_aggregate[] = {
ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
@@ -360,6 +368,26 @@
};
zend_function_entry *zend_funcs_traversable = NULL;
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_arrayaccess_offset, 0)
+ ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO();
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_arrayaccess_offset_value, 0)
+ ZEND_ARG_INFO(0, offset)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+zend_function_entry zend_funcs_arrayaccess[] = {
+ ZEND_ABSTRACT_ME(arrayaccess, offsetExists, arginfo_arrayaccess_offset)
+ ZEND_ABSTRACT_ME(arrayaccess, offsetGet, arginfo_arrayaccess_offset)
+ ZEND_ABSTRACT_ME(arrayaccess, offsetSet, arginfo_arrayaccess_offset_value)
+ ZEND_ABSTRACT_ME(arrayaccess, offsetUnset, arginfo_arrayaccess_offset)
+ {NULL, NULL, NULL}
+};
+
/* }}} */
#define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
@@ -383,6 +411,8 @@
REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
+
+ REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
}
/* }}} */
Index: ZendEngine2/zend_interfaces.h
diff -u ZendEngine2/zend_interfaces.h:1.2 ZendEngine2/zend_interfaces.h:1.3
--- ZendEngine2/zend_interfaces.h:1.2 Fri Nov 7 04:33:06 2003
+++ ZendEngine2/zend_interfaces.h Mon Nov 24 15:57:53 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_interfaces.h,v 1.2 2003/11/07 09:33:06 helly Exp $ */
+/* $Id: zend_interfaces.h,v 1.3 2003/11/24 20:57:53 helly Exp $ */
#include "zend.h"
#include "zend_API.h"
@@ -24,6 +24,7 @@
ZEND_API zend_class_entry *zend_ce_traversable;
ZEND_API zend_class_entry *zend_ce_aggregate;
ZEND_API zend_class_entry *zend_ce_iterator;
+ZEND_API zend_class_entry *zend_ce_arrayaccess;
ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce,
zend_function **fn_proxy, char *function_name, int function_name_len, zval
**retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC);
Index: ZendEngine2/zend_operators.c
diff -u ZendEngine2/zend_operators.c:1.167 ZendEngine2/zend_operators.c:1.168
--- ZendEngine2/zend_operators.c:1.167 Thu Nov 13 15:53:55 2003
+++ ZendEngine2/zend_operators.c Mon Nov 24 15:57:53 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_operators.c,v 1.167 2003/11/13 20:53:55 moriyoshi Exp $ */
+/* $Id: zend_operators.c,v 1.168 2003/11/24 20:57:53 helly Exp $ */
#include <ctype.h>
@@ -1410,7 +1410,7 @@
}
-ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce,
zend_class_entry *ce TSRMLS_DC)
+ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce,
zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC)
{
zend_uint i;
@@ -1419,16 +1419,23 @@
return 1;
}
}
- while (instance_ce) {
- if (instance_ce == ce) {
- return 1;
+ if (!interfaces_only) {
+ while (instance_ce) {
+ if (instance_ce == ce) {
+ return 1;
+ }
+ instance_ce = instance_ce->parent;
}
- instance_ce = instance_ce->parent;
}
return 0;
}
+ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce,
zend_class_entry *ce TSRMLS_DC)
+{
+ return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
+}
+
#define LOWER_CASE 1
#define UPPER_CASE 2
#define NUMERIC 3
Index: ZendEngine2/zend_operators.h
diff -u ZendEngine2/zend_operators.h:1.81 ZendEngine2/zend_operators.h:1.82
--- ZendEngine2/zend_operators.h:1.81 Wed Oct 29 12:45:56 2003
+++ ZendEngine2/zend_operators.h Mon Nov 24 15:57:54 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_operators.h,v 1.81 2003/10/29 17:45:56 moriyoshi Exp $ */
+/* $Id: zend_operators.h,v 1.82 2003/11/24 20:57:54 helly Exp $ */
#ifndef ZEND_OPERATORS_H
#define ZEND_OPERATORS_H
@@ -59,6 +59,7 @@
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2
TSRMLS_DC);
+ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce,
zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC);
ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce,
zend_class_entry *ce TSRMLS_DC);
static inline zend_bool is_numeric_string(char *str, int length, long *lval, double
*dval, zend_bool allow_errors)
Index: ZendEngine2/zend_object_handlers.c
diff -u ZendEngine2/zend_object_handlers.c:1.76 ZendEngine2/zend_object_handlers.c:1.77
--- ZendEngine2/zend_object_handlers.c:1.76 Mon Nov 10 15:44:50 2003
+++ ZendEngine2/zend_object_handlers.c Mon Nov 24 15:57:54 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_object_handlers.c,v 1.76 2003/11/10 20:44:50 helly Exp $ */
+/* $Id: zend_object_handlers.c,v 1.77 2003/11/24 20:57:54 helly Exp $ */
#include "zend.h"
#include "zend_globals.h"
@@ -26,6 +26,7 @@
#include "zend_objects.h"
#include "zend_objects_API.h"
#include "zend_object_handlers.h"
+#include "zend_interfaces.h"
#define DEBUG_OBJECT_HANDLERS 0
@@ -352,44 +353,49 @@
zval *zend_std_read_dimension(zval *object, zval *offset TSRMLS_DC)
{
-#if 1
- zend_error(E_ERROR, "Cannot use object as array");
-#else
- zend_printf("Fetching from object: ");
- zend_print_zval(object, 0);
-
- zend_printf("\n the offset: ");
- zend_print_zval(offset, 0);
-
- zend_printf("\n");
-#endif
- return EG(uninitialized_zval_ptr);
+ zend_class_entry *ce = Z_OBJCE_P(object);
+ zval *retval;
+
+ if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ zend_call_method_with_1_params(&object, ce, NULL, "offsetget",
&retval, offset);
+ if (retval->refcount > 0) { /* Should always be the case */
+ retval->refcount--;
+ }
+ return retval;
+ } else {
+ zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
+ return 0;
+ }
}
static void zend_std_write_dimension(zval *object, zval *offset, zval *value
TSRMLS_DC)
{
-#if 1
- zend_error(E_ERROR, "Cannot use object as array");
-#else
- zend_printf("Assigning to object: ");
- zend_print_zval(object, 0);
-
- zend_printf("\n with offset: ");
- zend_print_zval(offset, 0);
-
- zend_printf("\n the value: ");
- zend_print_zval(value, 0);
-
- zend_printf("\n");
-#endif
+ zend_class_entry *ce = Z_OBJCE_P(object);
+
+ if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ zend_call_method_with_2_params(&object, ce, NULL, "offsetset", NULL,
offset, value);
+ } else {
+ zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
+ }
}
static int zend_std_has_dimension(zval *object, zval *offset, int check_empty
TSRMLS_DC)
{
- zend_error(E_ERROR, "Cannot use object as array");
- return 0;
+ zend_class_entry *ce = Z_OBJCE_P(object);
+ zval *retval;
+ int result;
+
+ if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ zend_call_method_with_1_params(&object, ce, NULL, "offsetexists",
&retval, offset);
+ result = i_zend_is_true(retval);
+ zval_ptr_dtor(&retval);
+ return result;
+ } else {
+ zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
+ return 0;
+ }
}
@@ -463,7 +469,15 @@
static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC)
{
- zend_error(E_ERROR, "Cannot use object as array");
+ zend_class_entry *ce = Z_OBJCE_P(object);
+ zval *retval;
+
+ if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ zend_call_method_with_1_params(&object, ce, NULL, "offsetunset",
&retval, offset);
+ zval_ptr_dtor(&retval);
+ } else {
+ zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
+ }
}
Index: php-src/tests/classes/array_access_001.phpt
+++ php-src/tests/classes/array_access_001.phpt
--TEST--
ZE2 ArrayAccess
--SKIPIF--
<?php
if (!class_exists('ArrayAccess')) die('skip ArrayAccess not present');
?>
--FILE--
<?php
class Object implements ArrayAccess {
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
function offsetExists($index) {
echo __METHOD__ . "($index)\n";
return array_key_exists($index, $this->a);
}
function offsetGet($index) {
echo __METHOD__ . "($index)\n";
return $this->a[$index];
}
function offsetSet($index, $newval) {
echo __METHOD__ . "($index,$newval)\n";
return $this->a[$index] = $newval;
}
function offsetUnset($index) {
echo __METHOD__ . "($index)\n";
unset($this->a[$index]);
}
}
$obj = new Object;
var_dump($obj->a);
echo "===EMPTY===\n";
var_dump(empty($obj[0]));
var_dump(empty($obj[1]));
var_dump(empty($obj[2]));
var_dump(empty($obj['4th']));
var_dump(empty($obj['5th']));
var_dump(empty($obj[6]));
echo "===isset===\n";
var_dump(isset($obj[0]));
var_dump(isset($obj[1]));
var_dump(isset($obj[2]));
var_dump(isset($obj['4th']));
var_dump(isset($obj['5th']));
var_dump(isset($obj[6]));
echo "===offsetGet===\n";
var_dump($obj[0]);
var_dump($obj[1]);
var_dump($obj[2]);
var_dump($obj['4th']);
var_dump($obj['5th']);
var_dump($obj[6]);
echo "===offsetSet===\n";
echo "WRITE 1\n";
$obj[1] = 'Changed 1';
var_dump($obj[1]);
echo "WRITE 2\n";
$obj['4th'] = 'Changed 4th';
var_dump($obj['4th']);
echo "WRITE 3\n";
$obj['5th'] = 'Added 5th';
var_dump($obj['5th']);
echo "WRITE 4\n";
$obj[6] = 'Added 6';
var_dump($obj[6]);
var_dump($obj[0]);
var_dump($obj[2]);
$x = $obj[6] = 'changed 6';
var_dump($obj[6]);
var_dump($x);
echo "===unset===\n";
var_dump($obj->a);
unset($obj[2]);
unset($obj['4th']);
unset($obj[7]);
unset($obj['8th']);
var_dump($obj->a);
?>
===DONE===
--EXPECTF--
array(4) {
[0]=>
string(3) "1st"
[1]=>
int(1)
[2]=>
string(3) "3rd"
["4th"]=>
int(4)
}
===EMPTY===
object::offsetExists(0)
bool(false)
object::offsetExists(1)
bool(false)
object::offsetExists(2)
bool(false)
object::offsetExists(4th)
bool(false)
object::offsetExists(5th)
bool(true)
object::offsetExists(6)
bool(true)
===isset===
object::offsetExists(0)
bool(true)
object::offsetExists(1)
bool(true)
object::offsetExists(2)
bool(true)
object::offsetExists(4th)
bool(true)
object::offsetExists(5th)
bool(false)
object::offsetExists(6)
bool(false)
===offsetGet===
object::offsetGet(0)
string(3) "1st"
object::offsetGet(1)
int(1)
object::offsetGet(2)
string(3) "3rd"
object::offsetGet(4th)
int(4)
object::offsetGet(5th)
Notice: Undefined index: 5th in %sarray_access_001.php on line %d
NULL
object::offsetGet(6)
Notice: Undefined offset: 6 in %sarray_access_001.php on line %d
NULL
===offsetSet===
WRITE 1
object::offsetSet(1,Changed 1)
object::offsetGet(1)
string(9) "Changed 1"
WRITE 2
object::offsetSet(4th,Changed 4th)
object::offsetGet(4th)
string(11) "Changed 4th"
WRITE 3
object::offsetSet(5th,Added 5th)
object::offsetGet(5th)
string(9) "Added 5th"
WRITE 4
object::offsetSet(6,Added 6)
object::offsetGet(6)
string(7) "Added 6"
object::offsetGet(0)
string(3) "1st"
object::offsetGet(2)
string(3) "3rd"
object::offsetSet(6,changed 6)
object::offsetGet(6)
string(9) "changed 6"
string(9) "changed 6"
===unset===
array(6) {
[0]=>
string(3) "1st"
[1]=>
string(9) "Changed 1"
[2]=>
string(3) "3rd"
["4th"]=>
string(11) "Changed 4th"
["5th"]=>
string(9) "Added 5th"
[6]=>
string(9) "changed 6"
}
object::offsetUnset(2)
object::offsetUnset(4th)
object::offsetUnset(7)
object::offsetUnset(8th)
array(4) {
[0]=>
string(3) "1st"
[1]=>
string(9) "Changed 1"
["5th"]=>
string(9) "Added 5th"
[6]=>
string(9) "changed 6"
}
===DONE===
Index: php-src/tests/classes/array_access_002.phpt
+++ php-src/tests/classes/array_access_002.phpt
--TEST--
ZE2 ArrayAccess::offsetSet without return
--SKIPIF--
<?php
if (!class_exists('ArrayAccess')) die('skip ArrayAccess not present');
?>
--FILE--
<?php
class Object implements ArrayAccess {
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
function offsetExists($index) {
echo __METHOD__ . "($index)\n";
return array_key_exists($index, $this->a);
}
function offsetGet($index) {
echo __METHOD__ . "($index)\n";
return $this->a[$index];
}
function offsetSet($index, $newval) {
echo __METHOD__ . "($index,$newval)\n";
/*return*/ $this->a[$index] = $newval;
}
function offsetUnset($index) {
echo __METHOD__ . "($index)\n";
unset($this->a[$index]);
}
}
$obj = new Object;
var_dump($obj->a);
echo "===EMPTY===\n";
var_dump(empty($obj[0]));
var_dump(empty($obj[1]));
var_dump(empty($obj[2]));
var_dump(empty($obj['4th']));
var_dump(empty($obj['5th']));
var_dump(empty($obj[6]));
echo "===isset===\n";
var_dump(isset($obj[0]));
var_dump(isset($obj[1]));
var_dump(isset($obj[2]));
var_dump(isset($obj['4th']));
var_dump(isset($obj['5th']));
var_dump(isset($obj[6]));
echo "===offsetGet===\n";
var_dump($obj[0]);
var_dump($obj[1]);
var_dump($obj[2]);
var_dump($obj['4th']);
var_dump($obj['5th']);
var_dump($obj[6]);
echo "===offsetSet===\n";
echo "WRITE 1\n";
$obj[1] = 'Changed 1';
var_dump($obj[1]);
echo "WRITE 2\n";
$obj['4th'] = 'Changed 4th';
var_dump($obj['4th']);
echo "WRITE 3\n";
$obj['5th'] = 'Added 5th';
var_dump($obj['5th']);
echo "WRITE 4\n";
$obj[6] = 'Added 6';
var_dump($obj[6]);
var_dump($obj[0]);
var_dump($obj[2]);
$x = $obj[6] = 'changed 6';
var_dump($obj[6]);
var_dump($x);
echo "===unset===\n";
var_dump($obj->a);
unset($obj[2]);
unset($obj['4th']);
unset($obj[7]);
unset($obj['8th']);
var_dump($obj->a);
?>
===DONE===
--EXPECTF--
array(4) {
[0]=>
string(3) "1st"
[1]=>
int(1)
[2]=>
string(3) "3rd"
["4th"]=>
int(4)
}
===EMPTY===
object::offsetExists(0)
bool(false)
object::offsetExists(1)
bool(false)
object::offsetExists(2)
bool(false)
object::offsetExists(4th)
bool(false)
object::offsetExists(5th)
bool(true)
object::offsetExists(6)
bool(true)
===isset===
object::offsetExists(0)
bool(true)
object::offsetExists(1)
bool(true)
object::offsetExists(2)
bool(true)
object::offsetExists(4th)
bool(true)
object::offsetExists(5th)
bool(false)
object::offsetExists(6)
bool(false)
===offsetGet===
object::offsetGet(0)
string(3) "1st"
object::offsetGet(1)
int(1)
object::offsetGet(2)
string(3) "3rd"
object::offsetGet(4th)
int(4)
object::offsetGet(5th)
Notice: Undefined index: 5th in %sarray_access_002.php on line %d
NULL
object::offsetGet(6)
Notice: Undefined offset: 6 in %sarray_access_002.php on line %d
NULL
===offsetSet===
WRITE 1
object::offsetSet(1,Changed 1)
object::offsetGet(1)
string(9) "Changed 1"
WRITE 2
object::offsetSet(4th,Changed 4th)
object::offsetGet(4th)
string(11) "Changed 4th"
WRITE 3
object::offsetSet(5th,Added 5th)
object::offsetGet(5th)
string(9) "Added 5th"
WRITE 4
object::offsetSet(6,Added 6)
object::offsetGet(6)
string(7) "Added 6"
object::offsetGet(0)
string(3) "1st"
object::offsetGet(2)
string(3) "3rd"
object::offsetSet(6,changed 6)
object::offsetGet(6)
string(9) "changed 6"
string(9) "changed 6"
===unset===
array(6) {
[0]=>
string(3) "1st"
[1]=>
string(9) "Changed 1"
[2]=>
string(3) "3rd"
["4th"]=>
string(11) "Changed 4th"
["5th"]=>
string(9) "Added 5th"
[6]=>
string(9) "changed 6"
}
object::offsetUnset(2)
object::offsetUnset(4th)
object::offsetUnset(7)
object::offsetUnset(8th)
array(4) {
[0]=>
string(3) "1st"
[1]=>
string(9) "Changed 1"
["5th"]=>
string(9) "Added 5th"
[6]=>
string(9) "changed 6"
}
===DONE===
Index: php-src/tests/classes/array_access_003.phpt
+++ php-src/tests/classes/array_access_003.phpt
--TEST--
ZE2 ArrayAccess::offsetGet ambiguties
--SKIPIF--
<?php
if (!class_exists('ArrayAccess')) die('skip ArrayAccess not present');
?>
--FILE--
<?php
class Object implements ArrayAccess {
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
function offsetExists($index) {
echo __METHOD__ . "($index)\n";
return array_key_exists($index, $this->a);
}
function &offsetGet($index) {
echo __METHOD__ . "($index)\n";
switch($index) {
case 1:
$a = 'foo';
return $a . 'Bar';
case 2:
static $a=1;
return $a;
}
return $this->a[$index];
}
function offsetSet($index, $newval) {
echo __METHOD__ . "($index,$newval)\n";
if ($index==3) {
$this->cnt = $newval;
}
return $this->a[$index] = $newval;
}
function offsetUnset($index) {
echo __METHOD__ . "($index)\n";
unset($this->a[$index]);
}
}
$obj = new Object;
var_dump($obj[1]);
var_dump($obj[2]);
$obj[2]++;
var_dump($obj[2]);
?>
===DONE===
--EXPECTF--
object::offsetGet(1)
string(6) "fooBar"
object::offsetGet(2)
int(1)
object::offsetGet(2)
object::offsetGet(2)
int(2)
===DONE===
Index: php-src/tests/classes/array_access_004.phpt
+++ php-src/tests/classes/array_access_004.phpt
--TEST--
ZE2 ArrayAccess::offsetGet ambiguties
--SKIPIF--
<?php
if (!class_exists('ArrayAccess')) die('skip ArrayAccess not present');
?>
--FILE--
<?php
class Object implements ArrayAccess {
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
function offsetExists($index) {
echo __METHOD__ . "($index)\n";
return array_key_exists($index, $this->a);
}
function offsetGet($index) {
echo __METHOD__ . "($index)\n";
switch($index) {
case 1:
$a = 'foo';
return $a . 'Bar';
case 2:
static $a=1;
return $a;
}
return $this->a[$index];
}
function offsetSet($index, $newval) {
echo __METHOD__ . "($index,$newval)\n";
if ($index==3) {
$this->cnt = $newval;
}
return $this->a[$index] = $newval;
}
function offsetUnset($index) {
echo __METHOD__ . "($index)\n";
unset($this->a[$index]);
}
}
$obj = new Object;
var_dump($obj[1]);
var_dump($obj[2]);
$obj[2]++;
var_dump($obj[2]);
?>
===DONE===
--EXPECTF--
object::offsetGet(1)
string(6) "fooBar"
object::offsetGet(2)
int(1)
object::offsetGet(2)
Fatal error: Objects used as arrays in post/pre increment/decrement must return values
by reference in %sarray_access_004.php on line %d
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php