levelmax World 0 Tutorial
  1. 0
  2. 1
  3. 2
  4. 3
L
Level 0.2 ~10 min Target: PHPStan level 2

Reading PHPStan output

A wall of PHPStan errors feels like an accusation. It's more useful to treat each one as a small, specific claim: on this line, this thing doesn't add up, and here's why. Read the claim properly and the fix is usually obvious.

Anatomy of a diagnostic

Here's one error from this level's exercise, as PHPStan prints it on the command line:

 ------ -------------------------------------------------------
  Line   Basket.php
 ------ -------------------------------------------------------
  20     Call to an undefined method LineItem::getSubtotal().
         🪪  method.notFound
 ------ -------------------------------------------------------

It has four parts, and the results panel shows the same four:

Part Here What it tells you
File Basket.php Where PHPStan noticed the problem.
Line 20 The exact line. In the results panel, click the diagnostic to jump there.
Message Call to an undefined method LineItem::getSubtotal(). The claim, in plain words. It names the type PHPStan believes it's looking at: LineItem.
Identifier method.notFound A stable name for this kind of error.

The message is the important part, and the type it names is the most useful clue. PHPStan isn't saying getSubtotal() doesn't exist anywhere. It's saying it doesn't exist on LineItem. Either the method has a different name, or the variable isn't the type you think it is. Both happen a lot.

The identifier matters later. Messages can change wording between PHPStan versions, but method.notFound won't. You can search the docs for it, and in World 3 you'll use identifiers to ignore exactly one kind of error on a line instead of everything.

Reading a whole report

  • Work from the top. Earlier mistakes often cause later diagnostics, and one fix can clear several errors.
  • Two errors on one line usually have one cause. A typo in a docblock type can trip two separate checks at once.
  • The line is where PHPStan noticed, not always where you went wrong. A bad @param in a docblock is reported on the method's line, not the docblock's. When the reported line looks fine, look just above it.
  • Analyse again after each fix. It takes a second and stops you chasing errors that have already gone.

Quick check

1. PHPStan reports Call to an undefined method LineItem::getSubtotal(). with the identifier method.notFound. What is the identifier for?
2. Two diagnostics point at the same line. What's the best first assumption?

CHALLENGE

Someone renamed a few things in a hurry and Basket no longer works. PHPStan already knows where.

Click Analyse, then work through the report from the top. Click a diagnostic to jump to its line. Fix src/Basket.php until the tests pass and PHPStan is clean at level 2.

Running on PHP 8.3…

Run the tests, run PHPStan, or submit for both. Ctrl/⌘ + Enter submits from the editor.