diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0fe4a614..88b271d9 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1804,6 +1804,18 @@ class CompilerBase extends \PhpAot\Core\Translator if (isset($this->useFunctions[$fname])) { $possibleFunctionNames[] = $this->escapeNamespace($this->useFunctions[$fname]) . self::NAMESPACE_SEPARATOR . $fname; } + // 复杂命名空间规则,组合命名空间 + // 例子:use foo\bar; bar\fn(); + foreach ($this->useNamespaces as $use) { + $ns1 = explode('\\', $use); + $ns2 = explode('\\', $fname); + if ($ns1[array_key_last($ns1)] === $ns2[array_key_first($ns2)]) { + $ns = array_merge($ns1, $ns2); + array_splice($ns, array_key_last($ns1) + 1); + $possibleFunctionNames[] = $this->escapeNamespace(implode('\\', $ns)); + break; + } + } foreach ($possibleFunctionNames as $name) { // 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误 // 跳过,稍后再处理 @@ -2373,6 +2385,11 @@ class CompilerBase extends \PhpAot\Core\Translator return str_replace('\\', self::NAMESPACE_SEPARATOR, strtolower($ns)); } + protected function escapeZendFnName(string $fn): string + { + return str_replace('\\', '_', strtolower($fn)); + } + protected function escapeName(string $name): string { return strtolower($name); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index d4e7ccda..73925cc9 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -972,7 +972,7 @@ class Translator extends Preprocessor private function genFunctionWrapper(FunctionDef $functionDef): string { - $name = $functionDef->namespace ? $functionDef->namespace . '_' . $functionDef->name : $functionDef->name; + $name = $this->escapeZendFnName($functionDef->getNamespacedName()); $cppCode = 'ZEND_FUNCTION(' . $name . '){' . PHP_EOL; $fn = self::PREFIX . $this->getNativeName($functionDef->name, $functionDef->namespace); $cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef); diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 0db307d7..136f15c9 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -75,19 +75,19 @@ foreach ($this->functions as $functionDef): if ($this->buildMode === 'ext' and $functionDef->name === 'main') { continue; } + $zif_name = $this->escapeZendFnName($functionDef->getNamespacedName()); ?> namespace): ?> -namespace . '_' . $functionDef->name; ?> ZEND_NAMED_FE("escapeString($functionDef->getNamespacedName())?>", ZEND_FN(), arginfo_) - ZEND_FE(name?>, arginfo_name?>) + ZEND_FE(, arginfo_) ZEND_FE_END }; // clang-format on -static PHP_MINIT_FUNCTION(targetName?>) { +PHP_MINIT_FUNCTION(targetName?>) { // class/interface class entries classCeList as $ce): @@ -151,7 +151,7 @@ foreach ($this->nativeConstants as $name => $constant): } -static PHP_RINIT_FUNCTION(targetName?>) { +PHP_RINIT_FUNCTION(targetName?>) { php::request_init(); php_app_init(); @@ -166,7 +166,7 @@ static PHP_RINIT_FUNCTION(targetName?>) { return SUCCESS; } -static PHP_RSHUTDOWN_FUNCTION(targetName?>) { +PHP_RSHUTDOWN_FUNCTION(targetName?>) { php_app_clean(); php::request_shutdown(); return SUCCESS;