refactor(php): separate internal constants loading logic

- Extract internal constants loading into dedicated loadInternalConstants method
- Filter out user-defined constants from internal constants array
- Maintain backward compatibility with non-grouped constants format
- Add proper handling of constant groups to prevent runtime state inclusion
- Improve static expansion behavior for compile-time vs runtime constants
pull/15/head
韩天峰 2 months ago
parent 898c1fffdc
commit d767104e1c
  1. 3
      phpunit/code/compiler_api/const_decl.php
  2. 40
      phpunit/src/CompilerBaseApiTest.php
  3. 22
      src/Php/Translator.php

@ -0,0 +1,3 @@
<?php
const AOT_COMPILE_TIME_CONST = 123;

@ -173,6 +173,46 @@ class CompilerBaseApiTest extends TestCase
$this->assertSame('ZEND_LONG_MIN', $this->compiler->getConstValue('PHP_INT_MIN'));
}
public function testConstDeclarationsAreStaticallyExpanded(): void
{
$this->compiler->prepareFile($this->fixturePath('const_decl.php'));
$code = $this->invokeMethod(
'parseConstFetch',
new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('AOT_COMPILE_TIME_CONST'))
);
$this->assertSame(CompilerBase::CONST_VAR . 'AOT_COMPILE_TIME_CONST', $code);
}
public function testDefineConstantsAreNotStaticallyExpanded(): void
{
$internalConstants = $this->getPropertyValue('internalConstants');
$this->assertArrayHasKey('PHP_VERSION', $internalConstants);
$this->assertArrayNotHasKey('ROOT_PATH', $internalConstants);
$code = $this->invokeMethod(
'parseConstFetch',
new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('ROOT_PATH'))
);
$this->assertStringStartsWith('php::constant(nullptr, ', $code);
$this->assertStringNotContainsString(ROOT_PATH, $code);
}
public function testDynamicallyDefinedConstantsAreNotInternalConstants(): void
{
$name = 'AOT_USER_DEFINE_' . str_replace('.', '_', uniqid('', true));
define($name, 'runtime-value');
$compiler = CompilerTest::create($this->testDir);
$ref = new \ReflectionClass($compiler);
$prop = $ref->getProperty('internalConstants');
$prop->setAccessible(true);
$this->assertArrayNotHasKey($name, $prop->getValue($compiler));
}
// ========================================================================
// genAnonClassName
// ========================================================================

@ -128,7 +128,7 @@ class Translator extends Preprocessor
// 这样可以确保优先级:命令行 > YAML > 默认值
$this->internalFunctions = array_flip(get_defined_functions()['internal']);
unset($this->internalFunctions[self::ENTRY_FUNCTION]);
$this->internalConstants = get_defined_constants();
$this->internalConstants = $this->loadInternalConstants();
if ($this->climate->arguments->defined('help')) {
$this->showUsage();
exit(0);
@ -148,6 +148,26 @@ class Translator extends Preprocessor
$this->detectPlatform();
}
protected function loadInternalConstants(): array
{
$groups = get_defined_constants(true);
if (!is_array($groups)) {
return get_defined_constants();
}
$constants = [];
foreach ($groups as $groupName => $group) {
// 编译器进程中的用户常量属于被编译程序的运行时状态,不能在静态阶段展开。
if (strcasecmp((string) $groupName, 'user') === 0 || !is_array($group)) {
continue;
}
foreach ($group as $name => $value) {
$constants[$name] = $value;
}
}
return $constants;
}
/**
* 检测操作系统、编译器以及 Windows 平台的 PHP lib 文件
*/

Loading…
Cancel
Save