From 04fdbcc0e431b0e559b8044900c46d18bef986fa Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 28 Jan 2026 20:54:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E7=B1=BB?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E9=9C=80=E6=B1=82=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E5=92=8C=E6=95=B0=E7=BB=84=E5=B1=9E=E6=80=A7=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ClassDef 中添加 requireCtor 属性用于标记是否需要构造函数 - 简化数组类型默认值的生成逻辑,使用 ZVAL_EMPTY_ARRAY 替代复杂的临时变量处理 - 添加构造函数需求检查,在类使用非空数组作为属性默认值时验证构造函数存在性 - 在构造函数中初始化数组类型的属性默认值到对象属性 - 检测表达式数组类型并设置类构造函数需求标志 --- bin/gen_stub.php | 7 +------ src/Php/ClassDef.php | 1 + src/Php/Translator.php | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/bin/gen_stub.php b/bin/gen_stub.php index 33835225..aad6eaac 100755 --- a/bin/gen_stub.php +++ b/bin/gen_stub.php @@ -2395,12 +2395,7 @@ class EvaluatedValue $code .= "\tZVAL_STR(&$zvalName, $forStringDef);\n"; } } elseif ($this->type->isArray()) { - global $translator; - $tmpVar = $translator->genTmpVarName(); - $code .= "\tauto $tmpVar = " . $translator->parseExpr($this->expr) . ";\n"; - $code .= "\t{$tmpVar}.moveTo(&$zvalName);\n"; - $code .= "\tphp::global_vars[\"$varName\"] = $zvalName;\n"; - $code .= "\tZ_TYPE_FLAGS($zvalName) = 0;\n"; + $code .= "\tZVAL_EMPTY_ARRAY(&$zvalName);\n"; } else { throw new Exception("Invalid default value: " . print_r($this->value, true) . ", type: " . print_r($this->type, true)); } diff --git a/src/Php/ClassDef.php b/src/Php/ClassDef.php index 2cde0475..adaebf63 100644 --- a/src/Php/ClassDef.php +++ b/src/Php/ClassDef.php @@ -18,6 +18,7 @@ class ClassDef extends ClassLikeDef public array $constants = []; public array $implements = []; public string $extends = ''; + public bool $requireCtor = false; public int $flags; public function __construct(string $name, int $flags, string $namespace = '') diff --git a/src/Php/Translator.php b/src/Php/Translator.php index f695822e..3624d30b 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -645,6 +645,9 @@ class Translator extends Preprocessor } } $code = $this->genNativeMethod($methodCodes); + if ($this->classDef->requireCtor and !$this->classDef->hasMethod('__construct')) { + $this->fatalError($class, "Class `{$this->class}` uses a non-empty array as the default value for an property, and the constructor must be set."); + } $this->resetClass(); return $code; } @@ -714,6 +717,14 @@ class Translator extends Preprocessor $name = $classDef->getNamespacedName(); $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; + + foreach ($classDef->properties as $property) { + if ($property->type === self::TYPE_ARRAY and $property->default and $property->default !== self::TYPE_ARRAY . '{}') { + $propOffset = self::PREFIX . $this->getPropertyOffset($property->name, $classDef->name, $classDef->namespace); + $cppCode .= $this->getIndent() . 'this_.getPropertyIndirect(' . $propOffset . ') = ' . $property->default . ';' . PHP_EOL; + } + } + $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); $cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef); return $cppCode; @@ -919,6 +930,10 @@ class Translator extends Preprocessor foreach ($v->props as $prop) { $propDef = new PropertyDef($this->parseIdentifier($prop->name), $flags, $type); if ($prop->default) { + if ($prop->default->getType() == 'Expr_Array' and count($prop->default->items) > 0) { + $this->classDef->requireCtor = true; + $propDef->type = self::TYPE_ARRAY; + } $propDef->default = $this->parseIdentifier($prop->default); } $this->classDef->properties[$propDef->name] = $propDef;