Introducing the MustUseResult attribute

October 5th 2025


Code showing the MustUseResult attribute usage

The #[MustUseResult] attribute prevents subtle bugs, however due to a recent RFC I'd recommend another approach going forward.

Adding #[MustUseResult] (from the PHP language extensions library) to a function or method means that the result must be used by the calling code.

Consider a Money class like this:

final class Money {

  public function __construct(public readonly int $cents)
  {}

  #[MustUseResult]
  public function add(int $cents): self
  {
     return new self($cents + $this->cents);
  }
}

Note that the add method returns a new instance of Money, rather than updating the existing object.

On the face of it, the code below looks correct. However, the $money::cents property is not updated by calling the add method. Instead add returns a new instance of the Money object, this new object has the cents property set to 30.

$money = new Money(10);
$money->add(20); // This has no effect
echo $money->cents; // Value is 10 

Due to the #[MustUseResult] attribute, the code above would have an error on the $money->add(20); line:

Result returned by method must be used

The correct way of using the add method is:

$money = new Money(10);
$updated = $money->add(20);
echo $updated->cents; // Value is 30 

The#[MustUseResult] attribute helps developers use the code correctly.

Consider #[NoDiscard] instead

Since creating #[MustUseResult] PHP has introduced, from version 8.5, the #[NoDiscard] attribute. (RFC).

#[NoDiscard] and #[MustUseResult] do pretty much the same thing. A benefit of #[NoDiscard] is errors also are reported running the code and not just by static analysis.

Even if you are running PHP under 8.5, PHPStan still understands #[NoDiscard] and will report errors.

Using either #[NoDiscard] or #[MustUseResult] is a powerful way to document (to both developers and tools) the intention of how a method should be used, thus preventing bugs.

Related articles