PHP 8.5 Features : PHP NoDiscard Attribute to improve safety of APIs

Yogesh Kushwaha
By Yogesh Kushwaha

February 21, 2024 11:12 AM

PHP NoDiscard Attribute

Web APIs are crucial part of any #Back-End application and their safety is primary focus of any developer. Use PHP NoDiscard Attribute to secure API call.

 

#[\NoDiscard] Attribute

What happen if you forget to use the returned value of a function? many time we miss the usage of a retuened response from a function. But this will not break your application anymore as PHP 8.5 has introduced PHP NoDiscard Attribute #[\NoDiscard]

 

By adding the #[\NoDiscard] attribute to a function, PHP will check whether the returned value is consumed and emit a warning if it is not. This allows improving the safety of APIs where the returned value is important, but it's easy to forget using the return value by accident.

The associated (void) cast can be used to indicate that a value is intentionally unused. which means if you are not using this returned value then you must specify the void as return type.

 

#[\NoDiscard]
function getPhpVersion(): string
{
    return 'PHP 8.5';
}

getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void). 

 Above code can be corrected if you know that the returned value never be used.


function getPhpVersion(): void
{
    return 'PHP 8.5';
}

getPhpVersion();

Note: Even if a function has a return type of void it will still return a value, this value is always null.

 

Why using the returned value matters

When a backend function returns something, it’s usually conveying one of these:

  • New state
    • Immutable-style APIs (with* methods, value objects, DTO transforms)
    • e.g. User $updatedUser = $userService->changeEmail($user, $email);
  • Outcome of an operation
    • Boolean success/failure, status codes, error arrays, Result objects, etc.
    • e.g. $success = $orderService->placeOrder($cart);
  • Data to send back to the client
    • Query handlers, repository methods, etc.
    • e.g. $posts = $postRepository->findLatest();

Conclusion

  • Decide what each function is:

    • Query → returns data → may use #[\NoDiscard] if ignoring is dangerous.

    • Command → performs side effects → returns void → fail with exceptions.

  • For important returned values:

    • Mark methods with #[\NoDiscard("message explaining why")].

    • Fix any warnings where callers ignore those results.

  • For functions that shouldn’t return anything:

    • Change return type to void.

    • Throw exceptions on failure.

    • Let controllers/handlers translate exceptions into proper HTTP responses.

  • When intentionally discarding a #[\NoDiscard] result:

    • Use (void) yourFunction(); to clearly show it’s deliberate.