From e6c3e22f6e905bbdd48f84ddb9663dd8dd81c05c Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 20 Jun 2026 21:51:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0=E6=9C=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=8F=98=E9=87=8F=E6=A3=80=E6=9F=A5=E5=92=8C?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=A4=84=E7=90=86=E5=99=A8=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在属性访问时检查未定义变量并报告错误 - 初始化类对象处理器以支持对象操作 - 添加对未定义变量属性访问的测试用例 - 添加对未定义变量方法调用的测试用例 - 为动态代码中的类型化属性取消设置添加测试 --- phpunit/code/base-class-method.php | 29 +++++++++++++++++++++++++++++ phpunit/src/UndefineTest.php | 10 ++++++++++ src/Php/CompilerBase.php | 6 +++++- src/gen_stub.php | 5 +++++ tests/aot/class/unset-int-prop.phpt | 28 ++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 phpunit/code/base-class-method.php create mode 100644 tests/aot/class/unset-int-prop.phpt diff --git a/phpunit/code/base-class-method.php b/phpunit/code/base-class-method.php new file mode 100644 index 00000000..e5c17d7b --- /dev/null +++ b/phpunit/code/base-class-method.php @@ -0,0 +1,29 @@ +bar(); + } +} + +class FooChild extends FooBase { + function bar() + { + var_dump(__CLASS__); + } +} + +function bar(FooBase $o) +{ + $o->doSomething(); +} + +function main() { + $o = new FooChild(); + $o2 = any($o); + bar($o2); +} diff --git a/phpunit/src/UndefineTest.php b/phpunit/src/UndefineTest.php index aad5de6f..3924ec4b 100644 --- a/phpunit/src/UndefineTest.php +++ b/phpunit/src/UndefineTest.php @@ -17,4 +17,14 @@ class UndefineTest extends \BaseTest { $this->exec('Attempt to unset static property', 'unset-static-prop.php'); } + + public function testPropertyAccessOnUndefinedVar(): void + { + $this->exec('The variable `$obj` is undefined', 'undefined-prop-access.php'); + } + + public function testMethodCallOnUndefinedVar(): void + { + $this->exec('The variable `$obj` is undefined', 'undefined-method-call.php'); + } } \ No newline at end of file diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0607cabb..7ca938d4 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3975,7 +3975,11 @@ class CompilerBase extends \PhpAot\Core\Translator $object = $expr->var; $property = $expr->name; $id = $this->getPropertyIdentifier($expr, $object, $property); - $objectVar = $this->parseIdentifier($object); + $objectName = $this->parseIdentifier($object); + if ($this->isVarExpr($object) and !$this->hasVar($objectName)) { + $this->errorUndefinedVariable($object); + } + $objectVar = $objectName; $getProperty = $objectVar . '.attr(' . $id . ', ' . $this->escapeBool($update) . ')'; if ($expr->hasAttribute('nativePropertyDef') and $this->nativeTypes) { /** diff --git a/src/gen_stub.php b/src/gen_stub.php index cae09295..d6c1c4c7 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -3781,6 +3781,11 @@ class ClassInfo { $code .= $php80CondEnd; } + $code .= "\n\tstatic zend_object_handlers class_object_handlers;"; + $code .= "\n\tphp_aot_init_object_handlers(&class_object_handlers);"; + $code .= "\n\tclass_entry->default_object_handlers = &class_object_handlers;"; + $code .= "\n"; + $code .= "\n\treturn class_entry;\n"; $code .= "}\n"; diff --git a/tests/aot/class/unset-int-prop.phpt b/tests/aot/class/unset-int-prop.phpt new file mode 100644 index 00000000..4bf5b4ea --- /dev/null +++ b/tests/aot/class/unset-int-prop.phpt @@ -0,0 +1,28 @@ +--TEST-- +unset typed property via dynamic code +--FILE-- +value += 1; + var_dump($base->value); + + eval('function test(FooObject $obj) { + unset($obj->value); + }'); + + test($base); + var_dump($base->value); + + echo "done\n"; +} +?> +--EXPECT-- +int(43) +int(0) +done \ No newline at end of file