From fbeac08f203aa77cc5525a4c2c41e53d4352bf22 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 23 Apr 2026 13:25:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=B1=9E=E6=80=A7=E5=8F=98=E9=87=8F=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8C=E5=8F=96=E6=B6=88=E8=AE=BE=E7=BD=AE=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 getObjectPropVarName 方法用于生成对象属性变量名 - 新增 getObjectPropVarInfo 方法用于获取对象属性变量信息 - 新增 hasObjectPropVar 方法用于检查对象属性变量是否存在 - 将警告颜色从黄色更改为洋红色以提高可读性 - 在取消设置对象属性时添加不允许操作的警告提示 - 添加对整数类型属性取消设置的特殊处理逻辑 - 新增 unset-int-prop.php 示例文件演示属性取消设置行为 --- examples/error/unset-int-prop.php | 20 +++++++++++++++++++ src/Php/CompilerBase.php | 32 ++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 examples/error/unset-int-prop.php diff --git a/examples/error/unset-int-prop.php b/examples/error/unset-int-prop.php new file mode 100644 index 00000000..fca97d3b --- /dev/null +++ b/examples/error/unset-int-prop.php @@ -0,0 +1,20 @@ +x); + unset($this->x); + var_dump($this->x); + } +} + +function main() +{ + $o = new Test(); + $o->bar(); + var_dump($o->x); +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 34bdb477..f2a6c21c 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -686,6 +686,16 @@ class CompilerBase extends \PhpAot\Core\Translator return $class; } + protected function getObjectPropVarName(string $object, string $prop): string + { + return self::OBJECT_PROP . $object . self::NAMESPACE_SEPARATOR . $prop; + } + + protected function getObjectPropVarInfo(string $object, string $prop): array + { + return $this->context->objectProps[$this->getObjectPropVarName($object, $prop)]; + } + protected function getNativeName(string $fn, string $ns = '', string $class = ''): string { $names = []; @@ -1679,6 +1689,11 @@ class CompilerBase extends \PhpAot\Core\Translator return isset($this->context->localVars[$name]); } + protected function hasObjectPropVar(string $name): bool + { + return isset($this->context->objectProps[$name]); + } + protected function addFunction(string $name, FunctionDef $functionDef): void { $this->functions[$this->escapeFunction($name)] = $functionDef; @@ -2269,7 +2284,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function warning(Node $node, string $msg): void { - $this->climate->yellow("{$msg} in {$this->file}:{$node->getStartLine()}"); + $this->climate->magenta("{$msg} in {$this->file}:{$node->getStartLine()}"); } protected function errorUndefinedVariable(Variable $node): never @@ -3413,8 +3428,15 @@ class CompilerBase extends \PhpAot\Core\Translator $lines[] = $array . '.offsetUnset(' . $dim . ');'; } elseif ($this->isPropertyFetch($var)) { $object = $this->parseIdentifier($var->var); - $propName = $this->identifierToStr($var->name, literal: true); - $lines[] = $object . '.unsetProperty(' . $propName . ');'; + $lines[] = $object . '.unsetProperty(' . $this->identifierToStr($var->name, literal: true) . ');'; + if ($object === 'this_' and $this->isIdExpr($var->name)) { + $propName = $this->parseIdentifier($var->name); + if ($this->hasObjectPropVar($this->getObjectPropVarName($object, $propName))) { + $this->warning($var, "Unset of object property `{$propName}` is not allowed"); + $lines = []; + $lines[] = $this->getObjectPropVarName($object, $propName) . " = 0;"; + } + } } elseif ($this->isVarExpr($var)) { $name = $this->parseIdentifier($var); if (!$this->hasVar($name)) { @@ -3468,8 +3490,8 @@ class CompilerBase extends \PhpAot\Core\Translator */ $def = $expr->getAttribute('nativePropertyDef'); if ($def->type === self::TYPE_INT or $def->type === self::TYPE_FLOAT) { - $propVar = self::OBJECT_PROP . $objectVar . self::NAMESPACE_SEPARATOR . $this->parseIdentifier($property); - if (!isset($this->context->objectProps[$propVar])) { + $propVar = $this->getObjectPropVarName($objectVar, $this->parseIdentifier($property)); + if (!$this->hasObjectPropVar($propVar)) { $this->context->objectProps[$propVar] = [ 'type' => $def->type, 'getter' => $getProperty,