The Required, The Optional, The Useless, and The Weird: of 
In PHP, parentheses () aren’t just punctuation : they play different roles depending on where and how they’re used. Some are compulsory, others are optional, and a few are just useless clutter. And then, there’s the weird one: (cast). Let’s review all PHP parentheses usages down.
Compulsory Parentheses
The compulsory parentheses are the ones PHP needs to make sense of the code. No one can omit them, and the source won’t even compile without them, so they are compulsory.
Function definitions and method calls
And vice-versa, obviously.
<?php
$double = fn($x) => $x * 2; // Parameters require parentheses (unless none)
echo $double('hello'); // With Arguments
?>
Control structures like if, while, switch, match
Baked into the PHP parser, nothing much to add there.
<?php
if ($a > $b) {
echo match($b) {
1 => 'C',
default => 3
};
}
?>
Optional Parentheses
Sometimes, parentheses are allowed but not necessary, so it is up to the human in the room to decide if it makes the code clearer, or valid.
Grouping expressions
This often applies to math expression, and more generally, operators. One may even wonder, if operators evolved into functions, they probably brought the parentheses with them.
<?php $result = ($a + $b) * $c; // Required for proper precedence $result = $a * $c + $b * $c; // The above may be removed $result = ($you + $me) + $elephpants; // Required for clearer reading ?>
Such parentheses are optional, as the expression may be refactored without them. Not that it would help in anything, it’s just possible.
Operator precedence
Some expressions are not the same, with and without parentheses, thanks to operators precedence. Both are valid, and one is definitely more popular, and in the end, it is a choice.
<?php
// $c is a boolean
while ($c = foo() === 3) {}
// $c is an integer
while (($c = foo()) === 3) {}
// $c is an integer
while (3 === $c = foo()) {}
?>
Inverting the operators helps to make this more obvious, if not more readable.
Readability
All expressions use the operators precedence rules, but they are hard to read: at least, for some of us. Then, adding parentheses makes it more readable.
<?php
// if $x is not an instance of Foo
if (!$x instanceof Foo) {}
if (!($x instanceof Foo)) {}
// if $source is null, spread range(1,4), or spread it
$array = [...$source ?? range(1,4)];
$array = [...($source ?? range(1,4))];
?>
The equal sign
Actually, one operator that often needs clarification with parentheses is the = sign. An assignation has one of the lowest precedence among operators, and it never expands to the next expression, but rather only capture the next result.
<?php
function foo() { return 4;}
$d = 3 + $c = foo() + 5;
// $d = 12, C = 4
$d = 3 * $c = foo() + 5;
// $d = 17, C = 4
echo $d;
?>
Of course, it is also a confusing syntax from the beginning: just try to guess the execution order in such expressions.
Parentheses with new: inside
new operator works with or without parentheses. When the constructor requires any argument, the parentheses are compulsory.
When the constructor requires no arguments, then the parentheses become optional. They are usually recommended, as a common best practise.
<?php
class W {
function __construct($a) {}
}
$c = new W(1);
$a = new X; // valid
$b = new X(); // prefered
class X {}
$a = new X; // valid
$b = new X(); // prefered
?>
Parentheses with new: outside
new operator produces a new object. Sometimes, that object needs to be accessed immediately, for a method call, or a property read. At that point, the parentheses used to be compulsory.
When the constructor requires no arguments, then the parentheses become optional. They are usually recommended, as a common best practise.
Since PHP 8.4, it is possible to use the newly created object immediately, without parentheses. Or, to be precise, only with the constructor parentheses (see section just before).
<?php
class W {
public $property = 'a';
}
// before PHP 8.4
echo (new W)->property;
// after PHP 8.4
echo new W()->property;
?>
Useless Parentheses
There are places where parentheses are thought to be useful, but they are not. This is the case with all PHP language constructs, such as echo, print, include, etc.
<?php
echo('Hello'); // Works
echo 'Hello'; // Also works
?>
Here, the parentheses are accepted, like any other expression, as the single argument for the language construct. Parentheses forces the inner expression to be resolved, and passes the results to the outer expression.
First, this means that nesting parenthesis is completely arbitrary, and futile.
<php
echo((((((((('Hello')))))))))); // Works, but don't do it
?>
Secondly, it hides the fact that echo accepts multiple arguments, separated with a comma. In fact, to make the one-argument echo work, the strings must be concatenated first, to be useful.
<?php
echo('Hello'. ' ' . 'World'); // Hello World
echo 'Hello', ' ', 'World'; // Hello World
?>
echo is the only one with that hidden feature. print, include only accept one argument, and empty works only with parentheses.
The Weird Parentheses: casting, constants and functioncall
Finally, there is an odd bug in the parsing engine, that catches anything that resemble a cast, such as (float), (int)… etc. in normal syntax.
<?php const int = 3; var_dump(int); // Parse error: syntax error, unexpected token "(int)" ?>
So, the recommendation here is to avoid using castnames as global constants: int, float, array, string, void. Luckily, it is not a common behavior.
PHP parentheses usage
Parentheses are quite versatile in PHP, ranging from compulsory to down right useless or buggy. It is still a very convenient tool, in particular to manage priorities between operators. When in doubt, just use them.

