fix(compiler): 修复对未定义变量使用 ??= 时的编译错误

pull/20/head
Yurun 1 month ago
parent 559a8860a0
commit 0da07cb065
  1. 14
      src/Parser/AssignOpTrait.php
  2. 14
      tests/compiler/coalesce/assign-coalesce-undefined-var.phpt

@ -862,6 +862,17 @@ trait AssignOpTrait
protected function parseAssignOpCoalesce(Expr\AssignOp\Coalesce $expr): string
{
$this->checkLeftValue($expr->var);
// PHP 允许对未定义的简单变量使用 ??=(例如 `$a ??= 123`):
// 此时 isset 为 false,直接执行赋值。需要提前声明该局部变量,
// 否则 isset 检查会因变量未定义而报错。此处必须声明为 Type::VAR
// (Variant),使其初值为 NULL,从而 isset 在运行时正确判定为
// false 并执行赋值;若使用原生类型,isset 恒为 true 会导致取到
// 未初始化的默认值(如 int(0)、空字符串)。
if ($this->isVarExpr($expr->var) and !$this->hasVar($this->parseIdentifier($expr->var))) {
$this->addLocalVar($this->parseIdentifier($expr->var), Type::VAR);
}
$isset = $this->parseChainedExpr($expr->var, self::OP_ISSET);
$var = $this->parseWritableIdentifier($expr->var);
@ -878,9 +889,6 @@ trait AssignOpTrait
if ($this->isVarExpr($expr->expr) and !$this->hasVar($right)) {
$this->errorUndefinedVariable($expr->expr);
}
if ($this->isVarExpr($expr->var) and !$this->hasVar($var)) {
$this->addLocalVar($var, $this->getNormalAssignType($this->detectTypeOfExpr($expr->expr)));
}
return '(' . $isset . '?' . $var . ':(' . $var . ' = ' . $right . '))';
}

@ -0,0 +1,14 @@
--TEST--
assign coalesce on undefined variable
--FILE--
<?php
$a ??= 123;
var_dump($a);
$b ??= 'foo';
$b ??= 'bar';
var_dump($b);
?>
--EXPECT--
int(123)
string(3) "foo"
Loading…
Cancel
Save