diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 6c802724..0055c180 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2964,11 +2964,13 @@ function factorial($int)
 coalesce-expression:
    logical-inc-OR-expression-1   ??   expression
+   logical-inc-OR-expression-1   ??
 
**Semantics** @@ -2978,6 +2980,8 @@ Given the expression `e1 ?? e2`, if `e1` is set and not `NULL` (i.e. TRUE for evaluated, and the result becomes the result of the whole expression. There is a sequence point after the evaluation of `e1`. +Given the expression `e1??`, its semantics are equivalent to `e1 ?? e2` where `e2` is the constant value `NULL`. + Note that the semantics of `??` is similar to `isset` so that uninitialized variables will not produce warnings when used in `e1`. @@ -2990,12 +2994,18 @@ $arr = ["foo" => "bar", "qux" => NULL]; $obj = (object)$arr; $a = $arr["foo"] ?? "bang"; // "bar" as $arr["foo"] is set and not NULL +$a = $arr["foo"]??; // "bar" as $arr["foo"] is set and not NULL $a = $arr["qux"] ?? "bang"; // "bang" as $arr["qux"] is NULL +$a = $arr["qux"]??; // "bang" as $arr["qux"] is NULL $a = $arr["bing"] ?? "bang"; // "bang" as $arr["bing"] is not set +$a = $arr["bing"]??; // NULL as $arr["bing"] is not set $a = $obj->foo ?? "bang"; // "bar" as $obj->foo is set and not NULL +$a = $obj->foo??; // "bar" as $obj->foo is set and not NULL $a = $obj->qux ?? "bang"; // "bang" as $obj->qux is NULL +$a = $obj->qux??; // NULL as $obj->qux is NULL $a = $obj->bing ?? "bang"; // "bang" as $obj->bing is not set +$a = $obj->bing??; // NULL as $obj->bing is not set $a = NULL ?? $arr["bing"] ?? 2; // 2 as NULL is NULL, and $arr["bing"] is not set diff --git a/spec/19-grammar.md b/spec/19-grammar.md index d4df4ca3..fb7db0b0 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -660,6 +660,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# coalesce-expression: logical-inc-OR-expression-1 ?? expression + logical-inc-OR-expression-1 ?? assignment-expression: conditional-expression diff --git a/tests/expressions/coalesce_operator/unary.phpt b/tests/expressions/coalesce_operator/unary.phpt new file mode 100644 index 00000000..7e138f41 --- /dev/null +++ b/tests/expressions/coalesce_operator/unary.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test ?? operator (unary) +--FILE-- +boo = 7; + +$arr = [ + 2 => 7, + "foo" => "bar", + "foobar" => NULL, + "qux" => $obj, + "bing" => [ + "bang" + ] +]; + +function foobar() { + echo "called\n"; + return ['a']; +} + +var_dump($nonexistent_variable??); +echo PHP_EOL; +var_dump($var??); +var_dump($var2??); +echo PHP_EOL; +var_dump($obj->boo??); +var_dump($obj->bing??); +var_dump($arr["qux"]->boo??); +var_dump($arr["qux"]->bing??); +echo PHP_EOL; +var_dump($arr[2]??); +var_dump($arr["foo"]??); +var_dump($arr["foobar"]??); +var_dump($arr["qux"]??); +var_dump($arr["bing"][0]??); +var_dump($arr["bing"][1]??); +echo PHP_EOL; +var_dump(foobar()[0]??); +echo PHP_EOL; +function f($x) +{ + printf("%s(%d)\n", __FUNCTION__, $x); + return $x; +} + +$a = f(null)??; +?> +--EXPECTF-- +NULL + +int(7) +NULL + +int(7) +NULL +int(7) +NULL + +int(7) +string(3) "bar" +NULL +object(stdClass)#%d (%d) { + ["boo"]=> + int(7) +} +string(4) "bang" +NULL + +called +string(1) "a" + +f(0)