Menu

How PHPStan analyses traits

May 16, 2021 · 2 min read

Traits are a mechanism to reuse code. They’re copy-paste implemented at the language level. Contents of a used trait become part of the class that uses it.

Consider the following code:

trait FooTrait
{

	public function doFoo(): int
	{
		// Access to an undefined property FooTrait::$foo.
		// Or is it?
		return $this->foo;
	}

}

If PHPStan would approach trait analysis in a traditional way, it would report the error. But whether the error is real or not depends on the class that uses the trait:

class Foo
{

	// there's no property $this–>foo, error should be reported
	use FooTrait;

}

class Bar
{

	// the property exists, do not report the error
	use FooTrait;

	private int $foo;

}

PHPStan does not analyse traits in isolation, it analyses them only as part of a class that uses them. In order for a trait to be analysed, both the using class and the trait need to be in analysed paths. Traits that are used zero times will not be analysed at all. Trait that is used 10 times will be analysed 10 times.

Let’s say we have file Foo.php that contains class Foo and then FooTrait.php that contains trait FooTrait that’s used by class Foo.

  • If we run vendor/bin/phpstan analyse Foo.php, the trait will not be analysed.
  • If we run vendor/bin/phpstan analyse FooTrait.php, the trait will not be analysed.
  • If we run vendor/bin/phpstan analyse Foo.php FooTrait.php, the trait will be analysed.

This is also one of the reasons why you should always analyse your whole project.

© 2016–2024 Ondřej Mirtes