Published
- 5 min read
New in PHP 8.5: Marking Return Values as Important

Today, we'll explore one of the exciting features coming with PHP 8.5—the new #[NoDiscard] attribute to indicate important return values.
PHP 8.5 introduces a variety of compelling features. As a library author, I'm particularly thrilled by the addition of the built-in #[NoDiscard]
attribute, enabling developers to mark a function or method's return value as important.
Tip: You can read the full RFC at wiki.php.net.
How does the NoDiscard attribute work?
Using #[NoDiscard]
is straightforward—simply annotate your function or method. For example, marking a function that returns critical operation results, such as status flags or error messages, helps prevent accidental omission or unnoticed errors:
<?php
#[NoDiscard]
function processStuff(): array
{
return [];
}
Now, if the function is called without using its return value, PHP generates the following warning:
The return value of function processStuff() should either be used or intentionally ignored by casting it as (void).
Customizing the Warning Message
You can provide a custom message for greater clarity:
<?php
#[NoDiscard("because this is a batch processing function, and if any of the items fail, it returns the error details in an array instead of throwing an exception.")]
function processStuff(): array
{
return [];
}
This results in a more personalized warning:
The return value of function processStuff() is expected to be consumed, because this is a batch processing function, and if any of the items fail, it returns the error details in an array instead of throwing an exception.
Suppressing the Warning
Besides using the returned value (assigning or otherwise processing it), you can suppress this warning in several ways:
<?php
@processStuff(); // Error suppression operator
(void)processStuff(); // Explicit void cast
$_ = processStuff(); // If you're coming from Go ;)
However, beware of OPCache optimizations. If OPCache detects an unused instruction, it might optimize away the call, leading to inconsistencies between development and production environments.
<?php
(bool)processStuff(); // OPCache may ignore this because the result isn't used.
Using (void)
explicitly is safe since OPCache will not optimize away explicit void casts.
Where is it used?
In addition to being usable in your own code, the #[NoDiscard]
attribute is automatically applied to specific core PHP functions/methods, notably:
flock()
: Ignoring its false return value can lead to difficult-to-diagnose concurrency issues.- Setters of
DateTimeImmutable
: These methods do not modify the original instance but return a new one. Ignoring this return value does nothing, a common pitfall for new developers.
When is the Warning Triggered?
PHP triggers the warning immediately before the function call executes, offering a significant safety benefit. If your application converts warnings into exceptions (as Symfony does by default), the potentially dangerous code never executes:
<?php
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
$file = fopen("/tmp/test.txt", "r+");
flock($file, LOCK_EX);
// Safe to write to the file! Or is it? We don't know because we ignored the return value of flock()
fwrite($file, "Hello world!");
fclose($file);
In this example, the flock() is never called! The warning prevents the execution of potentially harmful code, ensuring issues are caught early during development.
Constraints
The use of #[NoDiscard]
comes with some logical constraints:
- It cannot be applied to functions with a
void
ornever
return type, as enforcing usage of a non-existent return value doesn't make sense. - It cannot be used on property hooks (getters/setters), as reading a property inherently means you're working with its value. Ignoring it would lead to unnecessary confusion and complexity.
So, what do you think? I personally find the #[NoDiscard]
attribute powerful and particularly valuable for library authors. I'm eagerly awaiting PHP 8.5 to incorporate this new feature into my own projects!