Some functions return a value you really need to check, and if you forget, a rare failure can slip by without a trace. This RFC from Tim Düsterhus and Volker Dusch adds a #[\NoDiscard] attribute. Put it on a function or method, and PHP warns you whenever a call ignores the return value. It also adds a (void) cast so you can mark a discarded value as intentional.
How it works
#[\NoDiscard("as processing might fail for individual items")] function bulk_process(array $items): array { // ... } // Warning: The return value of function bulk_process() is expected // to be consumed, as processing might fail for individual items bulk_process($items); // No warning, the value is assigned $results = bulk_process($items); // No warning, the (void) cast says it's on purpose (void)bulk_process($items);
The details:
- Userland functions raise an
E_USER_WARNING, and native functions raise anE_WARNING. - Your custom message is appended to the warning.
- Using the value in any way counts, even assigning it to a throwaway variable.
(void)is a statement, not an expression, soif ((void)foo())is a syntax error.- You can't use the attribute on
voidorneverfunctions, on magic methods like__construct, or on property hooks. - The check happens just before the call. With an error handler that throws, the function doesn't run at all.
The RFC also adds the attribute to the DateTimeImmutable::set*() methods. Those return a new object instead of modifying the existing one, which is easy to forget. The RFC planned to add it to flock() as well, but the page notes that part wasn't done.
The authors say the attribute is meant for functions where an ignored return value causes bugs that tests might not catch. A pure function like str_contains() isn't a good fit.
What it means for existing code
You can no longer declare a class named NoDiscard in the global namespace, though the RFC found no code that does. (void) used to be a valid way to read a constant named void, but again the RFC found no real code doing that. If you use a throwing error handler, a new warning could become an exception.
The vote
There were two votes, each needing a two-thirds majority, and both closed on March 19, 2025.
- The
#[\NoDiscard]attribute passed 18 to 4. - The
(void)cast passed 18 to 2.
Both shipped in PHP 8.5.