From 90f9da03689878434579c5620b0b4db5ad22840b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:50:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E4=B8=BA=E9=97=AD=E5=8C=85?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E6=B7=BB=E5=8A=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E5=92=8C=E5=8F=AF=E5=8F=98=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了必需参数数量计算和参数计数验证逻辑 - 添加了参数不足时抛出异常的功能 - 支持可变参数的循环获取和数组构建 - 实现了参数默认值的条件解析处理 - 集成了参数类型检查和引用参数错误处理 --- src/Php/Generator/ClosureGenerator.php | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 06193d73..c2654141 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -38,12 +38,45 @@ trait ClosureGenerator $this->context->inClosure = true; $this->indentLevel++; + $requiredArgCount = 0; + foreach ($params as $param) { + if ($param->variadic || $param->default !== null) { + break; + } + $requiredArgCount++; + } + if ($requiredArgCount > 0) { + $message = 'php::concat({' + . 'php::Str(' . $this->genCharPtr('Too few arguments to function {closure}(), ', true) . '), ' + . 'php::toString(php::getCallArgNum()), ' + . 'php::Str(' . $this->genCharPtr(' passed and exactly ' . $requiredArgCount . ' expected', true) . ')' + . '})'; + $code .= $this->getIndent() . 'if (UNEXPECTED(php::getCallArgNum() < ' . $requiredArgCount . ')) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'return php::throwException(zend_ce_argument_count_error, (' . $message . ').toCString());' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + } + foreach ($params as $i => $param) { if ($param->byRef) { $this->fatalError($expr, 'Closure cannot use reference parameter'); } $var = $this->parseIdentifier($param->var); - $code .= 'auto ' . $var . ' = php::getCallArg(' . $i . ');' . PHP_EOL; + if ($param->variadic) { + $code .= $this->getIndent() . self::TYPE_ARRAY . ' ' . $var . ';' . PHP_EOL; + $code .= $this->getIndent() . 'for (uint32_t i = ' . $i . '; i < php::getCallArgNum(); i++) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . $var . '.append(php::getCallArg(i));' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + $this->addArgument($var, self::TYPE_ARRAY); + continue; + } + $argExpr = $param->default === null + ? 'php::getCallArg(' . $i . ')' + : 'php::getCallArg(' . $i . ', ' . $this->parseParamDefaultValue($param->default) . ')'; + $code .= $this->getIndent() . 'auto ' . $var . ' = ' . $argExpr . ';' . PHP_EOL; $this->addArgument($var, self::TYPE_VAR); }