diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index d4bd369b..aec62adb 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -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) . '})'; } } diff --git a/src/Php/Reflection.php b/src/Php/Reflection.php index 6756a3a9..9dc89764 100644 --- a/src/Php/Reflection.php +++ b/src/Php/Reflection.php @@ -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; + } } diff --git a/tests/aot/array/array-multisort.phpt b/tests/aot/array/array-multisort.phpt new file mode 100644 index 00000000..55533dd6 --- /dev/null +++ b/tests/aot/array/array-multisort.phpt @@ -0,0 +1,32 @@ +--TEST-- +array_multisort() function - normal arguments +--FILE-- + 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) +} \ No newline at end of file