From f2647ccbbaaf11f140149736ad73ce6693be32c1 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 23 Mar 2026 14:03:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=94=AF=E6=8C=81=E7=B1=BB?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E6=95=B0=E7=BB=84=E7=B1=BB=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 CompilerBase.php 中添加对类常量数组类型的判断和处理逻辑 - 在 extension.cc.php 模板中增加类数组常量的声明、初始化和清理代码生成 - 修改 Translator.php 中的类常量解析逻辑以支持类型推断 - 添加对未明确声明类型的类常量进行自动类型检测 - 为类数组常量生成对应的外部变量声明 - 移除不再需要的字面字符串数组外部声明 --- src/Php/CompilerBase.php | 7 ++++++- src/Php/Translator.php | 25 ++++++++++++++++++---- src/template/extension.cc.php | 36 ++++++++++++++++++++++++++++++++ tests/aot/class-const-001.phpt | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 tests/aot/class-const-001.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index b5be87cf..32ade24b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3883,7 +3883,12 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->hasNativeClass($class)) { $classDef = $this->getClassDef($class); if ($classDef->hasConstant($const)) { - return $classDef->getConstant($const)->value; + $constInfo = $classDef->getConstant($const); + if ($constInfo->type === self::TYPE_ARRAY) { + return self::PREFIX . $this->getNativeName($constInfo->name, $classDef->namespace, $classDef->name); + } else { + return $constInfo->value; + } } if ($classDef->enum) { $ce = $this->getClassEntryPtr($class); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 93376c1f..23abc6e0 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -216,6 +216,15 @@ class Translator extends Preprocessor $propCount = count($this->propMap); $lines[] = 'extern uint32_t ' . self::PREFIX . self::PROP_MAP . '[' . $propCount . '];' . PHP_EOL; + foreach ($this->classes as $classDef) { + foreach ($classDef->constants as $constant) { + if ($constant->type === self::TYPE_ARRAY) { + $constName = self::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); + $lines[] = 'extern ' . self::TYPE_VAR . ' ' . $constName . ';' . PHP_EOL; + } + } + } + $code = implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; $this->writeFile($file, $code); } @@ -407,9 +416,6 @@ class Translator extends Preprocessor { $code = '#include ' . PHP_EOL; - $literalStringsCount = count($this->literalStrings); - $code .= 'extern ' . self::TYPE_STR . ' ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; - foreach ($this->nativeFunctions as $name => $func) { $code .= 'extern ' . $func->returnType . ' ' . self::PREFIX . $name . '('; $list = []; @@ -1038,8 +1044,19 @@ class Translator extends Preprocessor protected function parseClassConstDef(Node\Stmt\ClassConst $v): void { $flags = $v->flags; - $type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_CONST); + if ($v->type) { + $type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_CONST); + } else { + $type = null; + } foreach ($v->consts as $const) { + if ($type === null) { + $type = match ($const->value->getType()) { + 'Expr_Array' => self::TYPE_ARRAY, + 'Scalar_String' => self::TYPE_STR, + default => self::TYPE_VAR, + }; + } $constName = $this->parseIdentifier($const->name); $constInfo = new ConstantDef($constName, $flags, $type, $this->parseIdentifier($const->value)); $this->classDef->constants[$constInfo->name] = $constInfo; diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index fc525162..e5c873a1 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -79,6 +79,18 @@ foreach ($this->nativeConstants as $name => $const): type?> ; +// class array constants +classes as $classDef) : + foreach ($classDef->constants as $constant) : + if ($constant->type === Translator::TYPE_ARRAY) : + $constName = Translator::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); + echo Translator::TYPE_VAR . " " . $constName . ";\n"; + endif; + endforeach; +endforeach; +?> + // clang-format off static const zend_function_entry ext_functions[] = { PHP_FE(cli_set_process_title, arginfo_cli_set_process_title) @@ -142,6 +154,18 @@ foreach ($this->staticPropertyList as $prop): php::setStaticProperty(genCharPtr($prop->class, true)?>, genCharPtr($prop->name)?>, default?>); + + // class array constants +classes as $classDef) : + foreach ($classDef->constants as $constant) : + if ($constant->type === Translator::TYPE_ARRAY) : + $constName = Translator::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); + echo $constName . " = " . $constant->value . ";\n"; + endif; + endforeach; +endforeach; ?> } @@ -160,6 +184,18 @@ foreach ($this->nativeConstants as $name => $const): ?> .unset(); + + // class array constants +classes as $classDef) : + foreach ($classDef->constants as $constant) : + if ($constant->type === Translator::TYPE_ARRAY) : + $constName = Translator::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); + echo $constName . ".unset();\n"; + endif; + endforeach; +endforeach; +?> } PHP_RINIT_FUNCTION(getModuleName()?>) { diff --git a/tests/aot/class-const-001.phpt b/tests/aot/class-const-001.phpt new file mode 100644 index 00000000..dab25959 --- /dev/null +++ b/tests/aot/class-const-001.phpt @@ -0,0 +1,38 @@ +--TEST-- +class const 001 +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + string(3) "php" + [1]=> + string(4) "java" + [2]=> + string(3) "c++" + [3]=> + string(6) "golang" +} +string(3) "c++" +string(15) "string constant" +int(123) \ No newline at end of file