mirror of
https://github.com/php/pecl-php-operator.git
synced 2026-04-27 16:53:35 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a696708c54 | |||
| 679f719c2f | |||
| c2e6179363 | |||
| 8e9db3e04b | |||
| 50fb525c5a | |||
| cdf8e3e370 | |||
| 0a80128678 |
@@ -4,7 +4,6 @@
|
||||
ARG_ENABLE("operator", "enable operator overload support", "no");
|
||||
|
||||
if (PHP_OPERATOR != "no") {
|
||||
AC_DEFINE("ZEND_VM_KIND", 1, "CFLAGS_OPERATOR");
|
||||
EXTENSION("operator", "operator.c");
|
||||
}
|
||||
|
||||
|
||||
+176
-19
@@ -241,6 +241,81 @@ static inline int _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS, const char *m
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHP_OPERATOR_BINARY_ASSIGN_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_binary_assign_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static int _php_operator_binary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_value, free_prop, free_obj;
|
||||
zval *var = NULL, *value, *result;
|
||||
zend_bool increment_opline = 0;
|
||||
|
||||
free_prop.var = free_obj.var = NULL;
|
||||
switch (opline->extended_value) {
|
||||
case ZEND_ASSIGN_OBJ:
|
||||
case ZEND_ASSIGN_DIM:
|
||||
{
|
||||
zend_op *opdata = opline + 1;
|
||||
zval *object = php_operator_zval_ptr(&(opline->op1), &free_obj, execute_data TSRMLS_CC);
|
||||
zval *prop = php_operator_zval_ptr(&(opline->op2), &free_prop, execute_data TSRMLS_CC);
|
||||
|
||||
if (!object || Z_TYPE_P(object) != IS_OBJECT) {
|
||||
/* Let orignal handler throw error */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
increment_opline = 1;
|
||||
value = php_operator_zval_ptr(&(opdata->op1), &free_value, execute_data TSRMLS_CC);
|
||||
if (!value) {
|
||||
/* Shouldn't happen */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Plan A */
|
||||
if (opline->extended_value == ZEND_ASSIGN_OBJ &&
|
||||
Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
|
||||
zval **varpp = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, prop TSRMLS_CC);
|
||||
if (varpp) {
|
||||
var = *varpp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Plan B */
|
||||
if (opline->extended_value == ZEND_ASSIGN_OBJ &&
|
||||
Z_OBJ_HT_P(object)->read_property) {
|
||||
var = Z_OBJ_HT_P(object)->read_property(object, prop, BP_VAR_RW TSRMLS_CC);
|
||||
} else if (opline->extended_value == ZEND_ASSIGN_DIM &&
|
||||
Z_OBJ_HT_P(object)->read_dimension) {
|
||||
var = Z_OBJ_HT_P(object)->read_dimension(object, prop, BP_VAR_RW TSRMLS_CC);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
var = php_operator_zval_ptr(&(opline->op1), &free_obj, execute_data TSRMLS_CC);
|
||||
value = php_operator_zval_ptr(&(opline->op2), &free_value, execute_data TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!var || Z_TYPE_P(var) != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(var)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, var, methodname, methodname_len, value TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (opline->result.op_type != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
if (free_prop.var) zval_dtor(free_prop.var);
|
||||
if (free_value.var) zval_dtor(free_value.var);
|
||||
php_operator_set_result_ptr(result, opline, execute_data);
|
||||
execute_data->opline += increment_opline ? 2 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHP_OPERATOR_UNARY_ASSIGN_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
@@ -266,26 +341,88 @@ static inline int _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_ADD, "__add")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SUB, "__sub")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MUL, "__mul")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_DIV, "__div")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MOD, "__mod")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SL, "__sl")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SR, "__sr")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_CONCAT, "__concat")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_OR, "__bw_or")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_AND, "__bw_and")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_XOR, "__bw_xor")
|
||||
#define PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_assign_obj_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_unary_assign_obj_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_obj, free_prop;
|
||||
zval *result;
|
||||
zval *obj = php_operator_zval_ptr(&(opline->op1), &free_obj, execute_data TSRMLS_CC);
|
||||
zval *prop = php_operator_zval_ptr(&(opline->op2), &free_prop, execute_data TSRMLS_CC);
|
||||
zval *var = NULL;
|
||||
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BW_NOT, "__bw_not")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL, "__bool")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL_NOT, "__bool_not")
|
||||
if (!obj || Z_TYPE_P(obj) != IS_OBJECT || !prop) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_INC, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_DEC, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_INC, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_DEC, "__post_dec")
|
||||
if (Z_OBJ_HT_P(obj)->get_property_ptr_ptr) {
|
||||
zval **varpp = Z_OBJ_HT_P(obj)->get_property_ptr_ptr(obj, prop TSRMLS_CC);
|
||||
if (varpp) {
|
||||
var = *varpp;
|
||||
}
|
||||
}
|
||||
if (!var && Z_OBJ_HT_P(obj)->read_property) {
|
||||
var = Z_OBJ_HT_P(obj)->read_property(obj, prop, BP_VAR_RW TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!var || Z_TYPE_P(var) != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(var)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, var, methodname, methodname_len, NULL TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (opline->result.op_type != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
if (free_obj.var) { zval_dtor(free_obj.var); }
|
||||
if (free_prop.var) { zval_dtor(free_prop.var); }
|
||||
php_operator_set_result_ptr(result, opline, execute_data);
|
||||
execute_data->opline++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_ADD, "__add")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SUB, "__sub")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MUL, "__mul")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_DIV, "__div")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MOD, "__mod")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SL, "__sl")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SR, "__sr")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_CONCAT, "__concat")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_OR, "__bw_or")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_AND, "__bw_and")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_XOR, "__bw_xor")
|
||||
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BW_NOT, "__bw_not")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL, "__bool")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL_NOT, "__bool_not")
|
||||
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_ADD, "__assign_add")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SUB, "__assign_sub")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_MUL, "__assign_mul")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_DIV, "__assign_div")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_MOD, "__assign_mod")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SL, "__assign_sl")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SR, "__assign_sr")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_CONCAT, "__assign_concat")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_OR, "__assign_bw_or")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_AND, "__assign_bw_and")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_XOR, "__assign_bw_xor")
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_INC, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_DEC, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_INC, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_DEC, "__post_dec")
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_PRE_INC_OBJ, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_PRE_DEC_OBJ, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_POST_INC_OBJ, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_POST_DEC_OBJ, "__post_dec")
|
||||
|
||||
/* ***********************
|
||||
* Module Housekeeping *
|
||||
@@ -320,12 +457,31 @@ PHP_MINIT_FUNCTION(operator)
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BOOL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BOOL_NOT);
|
||||
|
||||
/* Binary Assign */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_ADD);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SUB);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_MUL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_DIV);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_MOD);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SR);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_CONCAT);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_OR);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_AND);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_XOR);
|
||||
|
||||
/* Unary Assign */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_INC);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_DEC);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_INC);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_DEC);
|
||||
|
||||
/* Unary Assign Obj */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_INC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_DEC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_INC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_DEC_OBJ);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -344,7 +500,8 @@ PHP_MSHUTDOWN_FUNCTION(operator)
|
||||
PHP_MINFO_FUNCTION(operator)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "operator overloading support", "+ - * / % << >> . | & ^ ~ ! ++ --");
|
||||
php_info_print_table_header(2, "operator overloading support", "+ - * / % << >> . | & ^ ~ ! ++ -- "
|
||||
"+= -= *= /= %= <<= >>= .= |= &= ^= ~=");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
|
||||
+22
-7
@@ -2,7 +2,7 @@
|
||||
<name>operator</name>
|
||||
<summary>Operator overloading for Objects</summary>
|
||||
<description>
|
||||
Operator overloading for +, -, *, /, %, <<, >>, ., |, &, ^, ~, and ! operators.
|
||||
Operator overloading for +, -, *, /, %, <<, >>, ., |, &, ^, ~, !, ++, -- += -= *= /= %= <<= >>= .= |= &= ^= and ~= operators.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<maintainers>
|
||||
@@ -14,12 +14,24 @@
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<state>beta</state>
|
||||
<date>2006-01-12</date>
|
||||
<notes>Initial Release</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.2</version>
|
||||
<state>beta</state>
|
||||
<date>2006-01-25</date>
|
||||
<notes>* Added support for pre/post inc/dec operators
|
||||
* Added support for assignment operators
|
||||
* Refactored opline->result handling
|
||||
* Refactored opcode handlers</notes>
|
||||
</release>
|
||||
|
||||
<changelog>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<state>beta</state>
|
||||
<date>2006-01-12</date>
|
||||
<notes>Initial Release</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
|
||||
<filelist>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
@@ -31,6 +43,9 @@
|
||||
<dir role="test" name="tests">
|
||||
<file role="test" name="unary.phpt"/>
|
||||
<file role="test" name="binary.phpt"/>
|
||||
<file role="test" name="incdec.phpt"/>
|
||||
<file role="test" name="binary_assign.phpt"/>
|
||||
<file role="test" name="binary_assign_objdim.phpt"/>
|
||||
</dir>
|
||||
</filelist>
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
#define PHP_OPERATOR_H
|
||||
|
||||
#define PHP_OPERATOR_EXTNAME "operator"
|
||||
#define PHP_OPERATOR_EXTVER "0.1"
|
||||
#define PHP_OPERATOR_EXTVER "0.2"
|
||||
|
||||
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 0
|
||||
typedef struct {
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
--TEST--
|
||||
Basic binary assign ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __assign_add($val) {
|
||||
return $this->value += $val;
|
||||
}
|
||||
|
||||
function __assign_sub($val) {
|
||||
return $this->value -= $val;
|
||||
}
|
||||
|
||||
function __assign_mul($val) {
|
||||
return $this->value *= $val;
|
||||
}
|
||||
|
||||
function __assign_div($val) {
|
||||
return $this->value /= $val;
|
||||
}
|
||||
|
||||
function __assign_mod($val) {
|
||||
return $this->value %= $val;
|
||||
}
|
||||
|
||||
function __assign_sl($val) {
|
||||
return $this->value <<= $val;
|
||||
}
|
||||
|
||||
function __assign_sr($val) {
|
||||
return $this->value >>= $val;
|
||||
}
|
||||
|
||||
function __assign_concat($val) {
|
||||
return $this->value .= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_or($val) {
|
||||
return $this->value |= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_and($val) {
|
||||
return $this->value &= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_xor($val) {
|
||||
return $this->value ^= $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
$c = new foo(4);
|
||||
|
||||
var_dump($c += 3);
|
||||
var_dump($c -= 3);
|
||||
var_dump($c *= 3);
|
||||
var_dump($c /= 2);
|
||||
var_dump($c %= 3);
|
||||
|
||||
$d = new foo(14);
|
||||
var_dump($d <<= 2);
|
||||
var_dump($d >>= 2);
|
||||
|
||||
$e = new foo('PHP');
|
||||
var_dump($e .= ' with');
|
||||
var_dump($e .= ' overloading');
|
||||
|
||||
$f = new foo(0x5A);
|
||||
var_dump($f |= 0xAA);
|
||||
var_dump($f &= 0xAA);
|
||||
var_dump($f ^= 0xAA);
|
||||
--EXPECT--
|
||||
int(7)
|
||||
int(4)
|
||||
int(12)
|
||||
int(6)
|
||||
int(0)
|
||||
int(56)
|
||||
int(14)
|
||||
string(8) "PHP with"
|
||||
string(20) "PHP with overloading"
|
||||
int(250)
|
||||
int(170)
|
||||
int(0)
|
||||
@@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
binary assign obj/dim ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __assign_add($val) {
|
||||
return $this->value += $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
class bar implements arrayaccess {
|
||||
public $baz;
|
||||
|
||||
function offsetget($ofs) {
|
||||
return $this->{$ofs};
|
||||
}
|
||||
|
||||
function offsetset($ofs,$val) { echo "argh"; }
|
||||
function offsetunset($ofs) { echo "oof"; }
|
||||
function offsetexists($ofs) { echo "ick"; return true; }
|
||||
}
|
||||
|
||||
$a = new foo(4);
|
||||
$b = new bar;
|
||||
$b->baz = $a;
|
||||
|
||||
var_dump($b->baz += 10);
|
||||
var_dump($b->baz += 5);
|
||||
var_dump($b['baz'] += 10);
|
||||
var_dump($b['baz'] += 5);
|
||||
--EXPECT--
|
||||
int(14)
|
||||
int(19)
|
||||
int(29)
|
||||
int(34)
|
||||
@@ -0,0 +1,65 @@
|
||||
--TEST--
|
||||
Inc/Dec obj ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __post_inc() {
|
||||
return $this->value++;
|
||||
}
|
||||
|
||||
function __post_dec() {
|
||||
return $this->value--;
|
||||
}
|
||||
|
||||
function __pre_inc() {
|
||||
$this->value++;
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function __pre_dec() {
|
||||
$this->value--;
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
class bar {
|
||||
public $baz;
|
||||
}
|
||||
|
||||
$c = new foo(7);
|
||||
$d = new bar;
|
||||
$d->baz = $c;
|
||||
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump($d->baz++);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump($d->baz--);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump(++$d->baz);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump(--$d->baz);
|
||||
}
|
||||
--EXPECT--
|
||||
int(7)
|
||||
int(8)
|
||||
int(9)
|
||||
int(10)
|
||||
int(9)
|
||||
int(8)
|
||||
int(8)
|
||||
int(9)
|
||||
int(10)
|
||||
int(9)
|
||||
int(8)
|
||||
int(7)
|
||||
Reference in New Issue
Block a user