refactor(php): 优化编译器参数引用检测逻辑

- 修改 CompilerBase.php 中 isPassedByReference 方法,增加对变长引用参数的支持
- 添加 Reflection::getVariadicParameter 方法用于获取可变参数的引用信息
- 修复 toReference 空链情况下的调用逻辑,改为使用成员函数形式
- 新增 array-multisort 函数的测试用例验证正常参数功能
pull/3/head
韩天峰 2 months ago
parent e0f6de8480
commit 397bfc9fbb
  1. 13
      src/Php/CompilerBase.php
  2. 32
      src/Php/Reflection.php
  3. 32
      tests/aot/array/array-multisort.phpt

@ -2941,7 +2941,14 @@ class CompilerBase extends \PhpAot\Core\Translator
} else {
$param = Reflection::getFunctionParameter($funcName, $argIndex);
}
return $param && $param->isPassedByReference();
if ($param) {
return $param->isPassedByReference();
}
// 参数索引超出声明范围,检查最后一个参数是否为变长引用参数(如 &...$rest)
$variadicParam = Reflection::getVariadicParameter($funcName, $className);
return $variadicParam !== null && $variadicParam->isPassedByReference();
}
protected function parseCallArgs(array $args, string $funcName = '', string $className = ''): string
@ -4478,6 +4485,10 @@ class CompilerBase extends \PhpAot\Core\Translator
$node->setAttribute('chainOpResult', $result);
return $fn . '(' . $var . ', {' . implode(', ', $list) . '}, ' . $result . ')';
} else {
// toReference(var, {}) 返回空引用,空链时改用成员函数形式
if ($op === self::OP_REFVAL && empty($list)) {
return $var . '.toReference()';
}
return $fn . '(' . $var . ', {' . implode(', ', $list) . '})';
}
}

@ -183,4 +183,36 @@ class Reflection
}
return $class->isAbstract();
}
/**
* 当参数索引超出声明范围时,尝试将最后一个参数作为变长参数(...$rest)获取。
* 返回变长参数对象或 null。
*/
public static function getVariadicParameter(string $funcName, string $className = ''): ?\ReflectionParameter
{
if ($className) {
$classRef = self::getClass($className);
if (!$classRef) {
return null;
}
try {
$params = $classRef->getMethod($funcName)->getParameters();
} catch (\ReflectionException) {
return null;
}
} else {
$funcRef = self::getFunction($funcName);
if (!$funcRef) {
return null;
}
$params = $funcRef->getParameters();
}
if (empty($params)) {
return null;
}
$lastParam = end($params);
return $lastParam->isVariadic() ? $lastParam : null;
}
}

@ -0,0 +1,32 @@
--TEST--
array_multisort() function - normal arguments
--FILE--
<?php
function main() {
$ar1 = array("row1" => 2, "row2" => 1, "row3" => 1);
$ar2 = array("row1" => 2, "row2" => "aa", "row3" => "1");
echo "\n-- Testing array_multisort() function with all normal arguments --\n";
var_dump(array_multisort($ar1, SORT_ASC, SORT_REGULAR, $ar2, SORT_DESC, SORT_STRING) );
var_dump($ar1, $ar2);
}
?>
--EXPECT--
-- Testing array_multisort() function with all normal arguments --
bool(true)
array(3) {
["row2"]=>
int(1)
["row3"]=>
int(1)
["row1"]=>
int(2)
}
array(3) {
["row2"]=>
string(2) "aa"
["row3"]=>
string(1) "1"
["row1"]=>
int(2)
}
Loading…
Cancel
Save