I've always been bothered by any redundancy or duplication in code. I wrote about it many years ago. Looking at this code just makes me suffer:
interface ContainerAwareInterface
{
/**
* Sets the container.
*/
public function setContainer(ContainerInterface $container = null);
}
Let's set aside the unnecessary commentary on the method for now. And this
time also the misunderstanding of dependency injection, if a library needs such
an interface. The fact that using the word Interface
in the name of
an interface is, in turn, a sign of not understanding object-oriented
programming, I'm planning a separate article on that. After all, I've been there
myself.
But why on earth specify the visibility as public
? It's a pleonasm. If it wasn't public,
then it wouldn't be an interface, right? And then someone thought to make it a
“standard” ?♂️
Sorry for the long introduction, what I'm getting to is whether to write optional nullable types with or without a question mark. So:
// without
function setContainer(ContainerInterface $container = null);
// with
function setContainer(?ContainerInterface $container = null);
Personally, I have always leaned towards the first option, because the information given by the question mark is redundant (yes, both notations mean the same from the language's perspective). This is how all the code was written until the arrival of PHP 7.1, the version that added the question mark, and there would have to be a good reason to change it suddenly.
With the arrival of PHP 8.0, I changed my mind and I'll explain why. The question mark is not optional in the case of properties. PHP will throw an error in this case:
class Foo
{
private Bar $foo = null;
}
// Fatal error: Default value for property of type Bar may not be null.
// Use the nullable type ?Bar to allow null default value
And from PHP 8.0 you can use promoted properties, which allows you to write code like this:
class Foo
{
public function __construct(
private ?Bar $foo = null,
string $name = null,
) {
// ...
}
}
Here you can see the inconsistency. If ?Bar
is used (which is
necessary), then ?string
should follow on the next line. And if
I use the question mark in some cases, I should use it in all cases.
The question remains whether it is better to use a union type
string|null
instead of a question mark. For example, if I wanted
to write Stringable|string|null
, maybe the version with a question
mark isn't at all necessary.
Update: It looks like PHP 8.4 will require the notation with a question mark.
Leave a comment