PHP 8.0: Expressions can now throw Exceptions


Prior to PHP 8.0, it was not allowed to throw an exceptions in when a single expression is expected. It is now possible to throw an exception in arrow functions, ternary expressions, or anywhere else the PHP parser expects a single expression.

Arrow Functions:

$fn = fn() => throw new \Exception('oops');

Ternary expressions:

$value = isset($_GET['value'])
    ? $_GET['value']
    : throw new \InvalidArgumentException('value not set');

$value ??= throw new \InvalidArgumentException('value not set');

$foo = $bar ?: throw new \InvalidArgumentException('$bar is falsy');

$foo = $bar ?? throw new \InvalidArgumentException('$bar is not set');

All of the snippets above are allowed since PHP 8.0.

Versions prior to 8.0 trigger a parse error:

Parse error: syntax error, unexpected 'throw' (T_THROW) in ... on line ...

Backwards Compatibility Impact

Using throw in an expression previously triggered a parse error, so there should be no practical breaking changes when you upgrade to PHP 8.

However, note that there is no way to make any code that throw in an expression work seamless in PHP versions prior to PHP 8. If compatibility with older versions is a concerns hold off using throw in expressions.

RFC GitHub PR Discussion Implementation