Use PHP NoDiscard where losing a result breaks the contract
Choose consequential PHP return values for NoDiscard, distinguish deliberate void casts from accidental loss, and keep warnings separate from correctness.
Some functions do their useful work by returning a value. Calling one and throwing the result away can leave the program looking busy while its intended state never changes. PHP's NoDiscard attribute gives API authors a way to flag that mistake. It is most valuable where losing a result breaks the caller's contract, rather than as a decoration on every method that returns something.
PHP 8.5 was released on 20 November 2025. The release announcement includes NoDiscard among its additions. The date matters: the release-candidate testing announcement earlier that month was not the stable release. PHP's 2025 archive records the separate announcements.
The mechanism has a deliberately narrow purpose. Mark a function or method with #[\NoDiscard], and PHP warns if its return value is not used. A deliberate (void) cast suppresses that warning. The PHP manual documents both behaviours. Neither says that the caller interpreted the value correctly or that the operation succeeded.
Start with the consequence of losing the value
An immutable value object offers a useful hypothetical case. A method that returns a modified copy leaves the original unchanged. If a caller assumes mutation and discards the copy, the requested change disappears from the caller's subsequent work. The important property is the contract between method and caller, not whether the return type happens to be an object.
A result containing individual failures is another candidate. The function may complete its work while returning information the caller needs to inspect. Silently losing that result can hide incomplete work. Here the attribute draws attention to an obligation that should also be explained in the API's documentation. A diagnostic cannot replace the explanation of what the result means.
The selection question is concrete: what can go wrong if a reasonable caller overlooks this result? If the answer identifies a likely defect, the annotation can make that mistake visible earlier. If the answer is merely that using return values is generally tidy, the annotation may add little. Consequence is a better criterion than the number of getters in a class.
A warning leaves work for the caller
Assigning a result to a variable counts as using it, but an assignment alone cannot establish that the caller checks a failure or keeps a transformed value. A programmer can also pass the value to another function that ignores its meaning. NoDiscard detects one syntactic pattern of loss. Correct treatment of the result remains a semantic property of the program.
That boundary should shape how a team responds to warnings. Repair the mistaken assumption in the caller. Do not make an otherwise unused variable solely to quiet the diagnostic and then describe the API as safe. The variable may remove the visible symptom while preserving the original failure to account for the result.
The emitted warning is not an exception contract. Applications can have their own error handling policies, but those policies are a separate layer. An API author should not promise that NoDiscard will stop an operation, roll back changes or force a recovery branch. The documented guarantee concerns the diagnostic for an unused result.
Deliberate discard should explain the intention
A (void) cast makes a purposeful discard explicit in PHP 8.5. That can be appropriate when a call has a side effect the caller wants and a result it genuinely does not need. The cast gives a reviewer a place to examine that choice. Its presence does not prove that the choice was correct.
A useful review asks whether the ignored information could change what happens next. If it describes a partial failure, the explanation for discarding it needs to account for that failure. If another part of the program already owns the outcome, make that responsibility clear in the surrounding design. Intention deserves a reason grounded in the operation, not a blanket exemption.
Compatibility matters when a library supports older PHP versions. The current manual says the attribute has no effect before PHP 8.5, while the (void) cast is unsupported there. It also documents declaration-specific behaviour for implemented and overridden methods. Those current manual notes should be checked against the supported runtime matrix; they are not evidence that every detail appeared in the launch announcement.
Broad annotation can make the signal worse
The strongest counterargument is warning fatigue. If every getter receives the attribute, callers may learn to suppress warnings mechanically. APIs sometimes allow a result to be ignored legitimately, and a diagnostic that appears on ordinary accepted usage can reduce attention to consequential mistakes. Selectivity is part of making the warning useful.
That does not mean getters are categorically unsuitable. A method's name or category cannot settle the decision. A seemingly simple read may be valuable only through its result, making an ignored call suspicious. Another method may return optional convenience information alongside its main side effect. Evaluate those contracts individually rather than applying a class-wide rule.
For existing libraries, adding diagnostics also changes the experience of callers. Start with a small set of methods whose results have clear obligations. Document why each matters and inspect representative calling patterns before expanding the set. This is a recommendation for adoption, not a claim of measured warning reduction or a completed migration.
The attribute is also an opportunity to reconsider ambiguous APIs. If callers routinely disagree about mutation or returned failure information, a clearer name or a different result contract may address more than one warning. NoDiscard can expose the confusion, but it should not be used to preserve a confusing design indefinitely.
In software maintenance, the useful outcome is a caller that accounts for a consequential result. Apply the attribute where accidental loss has a specific meaning, allow explicit discard when the operation justifies it, and assess the surrounding behaviour separately. A quieter warning stream is helpful only if the program's obligations are still being met.
Paul