Some functions are only useful for the value they return. If you call one and throw that value away, you almost certainly made a mistake. PHP 8.5 adds the #[\NoDiscard] attribute, which tells PHP to warn you when a function's return value is ignored. It catches a subtle, common class of bug.
Like #[\Deprecated] from the previous version, this is an attribute - a small label in #[...] you attach to a function. You're just using the one PHP provides.
The bug it prevents
Look at this function. It doesn't change anything in place - it returns a new, cleaned-up string:
<?php
function sanitize(string $input): string {
return trim(strip_tags($input));
}
$comment = ' <b>Nice!</b> ';
sanitize($comment); // BUG: the result is thrown away!
echo $comment; // still " <b>Nice!</b> " - nothing was cleaned
The call to sanitize($comment) looks like it does something, but its whole purpose is the value it returns - and we ignored it. $comment is unchanged. This kind of bug is easy to miss because the code looks correct and runs without any error.
Marking the function with #[\NoDiscard]
Add #[\NoDiscard] above the function to say "the caller must use my return value":
<?php
#[\NoDiscard]
function sanitize(string $input): string {
return trim(strip_tags($input));
}
sanitize($comment); // Warning: return value of sanitize() is discarded
Now PHP raises a warning the moment you call sanitize() without doing anything with the result. The mistake surfaces immediately instead of hiding as wrong data later.
Adding a message
You can include a short note explaining why the value matters, just like with #[\Deprecated]:
<?php
#[\NoDiscard(message: "assign the cleaned string to a variable")]
function sanitize(string $input): string {
return trim(strip_tags($input));
}
The message appears in the warning, guiding whoever made the mistake toward the fix.
Fixing the warning: use the value
The obvious fix is to actually use what comes back:
<?php
$clean = sanitize($comment); // no warning - we used the result
echo $clean; // Nice!
When you really do want to ignore it
Once in a while you genuinely mean to discard the value - maybe you're calling the function only for a side effect in that one spot. To silence the warning on purpose, cast the call to (void):
<?php
(void) sanitize($comment); // "yes, I meant to ignore this"
The (void) cast is a clear signal to PHP - and to the next person reading the code - that ignoring the result was intentional, not an accident.
Where this is most useful
#[\NoDiscard] fits functions whose return value is the whole point:
- Functions that return a new value instead of modifying their argument (like our
sanitize). - Functions that return a result you must check, such as a success flag or a validation outcome.
- "Builder" style methods that return a new object rather than changing the current one.
For these, silently dropping the return value is nearly always a bug - which is exactly what the attribute is there to catch.
Summary
- PHP 8.5's
#[\NoDiscard]attribute warns when a function's return value is ignored. - It targets functions whose only purpose is the value they return.
- Add
message:to explain what the caller should do with the value. - Fix the warning by using the return value, or cast the call to
(void)when you mean to ignore it.
FAQ
What does #[\NoDiscard] do in PHP 8.5?
It marks a function so that PHP emits a warning whenever the function is called but its return value isn't used. It's meant for functions whose result is their whole purpose.
How do I intentionally ignore the return value?
Cast the call to (void), for example (void) sanitize($comment);. This tells PHP the discard is deliberate and suppresses the warning.
How is it different from #[\Deprecated]?
#[\Deprecated] warns that a function itself is outdated. #[\NoDiscard] warns that you called a still-valid function but forgot to use what it returned. They solve different problems.