PHP 拡張 演算子オーバーロード
$ git diff diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index cf3a908..27c27a2 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -30,6 +30,7 @@ #include "zend_strtod.h" #include "zend_exceptions.h" #include "zend_closures.h" +#include "zend_interfaces.h" #if ZEND_USE_TOLOWER_L #include <locale.h> @@ -794,6 +795,13 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * zval op1_copy, op2_copy; int converted = 0; + if (Z_TYPE_P(op1) == IS_OBJECT && zend_hash_exists(&Z_OBJCE_P(op1)->function_table, "__add", strlen("__add") + 1)) { + zval* tmp; + zend_call_method_with_1_params(&op1, NULL, NULL, "__add", &tmp, op2); + ZVAL_ZVAL(result, tmp, 0, 1); + return SUCCESS; + } + while (1) { switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) { case TYPE_PAIR(IS_LONG, IS_LONG): { @@ -856,6 +864,13 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * zval op1_copy, op2_copy; int converted = 0; + if (Z_TYPE_P(op1) == IS_OBJECT && zend_hash_exists(&Z_OBJCE_P(op1)->function_table, "__sub", strlen("__sub") + 1)) { + zval* tmp; + zend_call_method_with_1_params(&op1, NULL, NULL, "__sub", &tmp, op2); + ZVAL_ZVAL(result, tmp, 0, 1); + return SUCCESS; + } +
makeしておく
hoge.php
<?php class Hoge { function __construct($value) { $this->value = $value; } function __add(Hoge $right) { return new Hoge($this->value + $right->value); } function __sub(Hoge $right) { return new Hoge($this->value - $right->value); } } $hoge = new Hoge(10) + new Hoge(2) - new Hoge(5); var_dump($hoge);
実行するとこんな感じ
sapi/cli/php hoge.php object(Hoge)#1 (1) { ["value"]=> int(7) }