feat(php): 实现 compact 函数支持并增强函数重定义检查

- 添加 compact 函数的功能实现和语法优化
- 移除 UNSUPPORTED_FUNCTIONS 列表中的 compact 条目
- 在 Preprocessor 中添加防止重定义内置函数的检查
- 实现 genCompact 方法来处理 compact 函数调用
- 添加测试用例验证 compact 函数功能正确性
- 增强错误处理机制以捕获非法变量使用情况
pull/1/head
韩天峰 4 months ago
parent 165d683f5a
commit 8865796b43
  1. 1
      src/Php/Constants.php
  2. 28
      src/Php/FuncCallOptimizer.php
  3. 4
      src/Php/Preprocessor.php
  4. 22
      tests/aot/functions/compact.phpt

@ -58,7 +58,6 @@ class Constants
];
public const UNSUPPORTED_FUNCTIONS = [
'compact',
'extract',
];
}

@ -126,6 +126,9 @@ trait FuncCallOptimizer
return 'true';
}
}
if ($name === 'compact') {
return $this->genCompact($expr);
}
if ($name === 'get_class') {
return $this->genGetClass($expr);
}
@ -166,4 +169,29 @@ trait FuncCallOptimizer
}
return 'php::fn::get_class(' . $this->parseIdentifier($object) . ')';
}
protected function genCompact(Node\Expr\FuncCall $expr): string
{
$list = [];
$this->indentLevel++;
foreach ($expr->args as $arg) {
if (!$this->isScalarString($arg->value)) {
$this->fatalError($expr, 'The argument of compact function can only be literal string');
}
$var = $arg->value->value;
if (!$this->hasVar($var)) {
$this->errorUndefinedVariable($var);
}
if ($this->isSuperGlobal($var)) {
$this->fatalError($expr, 'Cannot use super global variable `' . $var . '` in compact function');
}
$key = $this->getLiteralString($var);
$list[] = $this->getIndent() . '{ ' . $key . '.str(), ' . $var . ' }';
}
$this->indentLevel--;
return $this->genArray($list);
}
}

@ -369,6 +369,10 @@ class Preprocessor extends CompilerBase
if ($this->hasFunction($name)) {
$this->fatalError($v, "Duplicate function `{$name}`");
}
// 禁止重定义内置函数
if (!$this->methodDef and $this->isInternalFunction($name)) {
$this->fatalError($v, "The function `{$name}` is a built-in function and cannot be redefined");
}
$functionDef = $this->parseFunctionDecl($v);
$this->addFunction($name, $functionDef);
if ($this->methodDef) {

@ -0,0 +1,22 @@
--TEST--
compact
--FILE--
<?php
function main()
{
$city = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";
$result = compact("event", "city", "state");
var_dump($result);
}
?>
--EXPECT--
array(3) {
["event"]=>
string(8) "SIGGRAPH"
["city"]=>
string(13) "San Francisco"
["state"]=>
string(2) "CA"
}
Loading…
Cancel
Save