- Edited
i did a bit of google searching and saw PHPStan (which was mentinoed by @benanamen ) and decided to give it a try. You can install it with composer:
composer require --dev phpstan/phpstan
If you just run it, it will not detect undeclared properties, but if you add the -l
flag with a level of 2 or higher, it will report 'undefined properties'. I created these files in a subdir, foo:
foo.php
<?php
class FooClass {
// blah blah blah
}
file.php
<?php
require_once 'foo.php';
$foo = new FooClass();
$foo->some_new_property = 42;
and ran it:
$ vendor/bin/phpstan analyse -l 2 foo
3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ---------------------------------------------------------------
Line file.php
------ ---------------------------------------------------------------
4 Access to an undefined property FooClass::$some_new_property.
------ ---------------------------------------------------------------
[ERROR] Found 1 error
This looks quite helpful. If anyone has experience with PHPStan or other static analysis tools, I'd be curious to hear any war stories.
EDIT: I got to wondering if PHPStan was smart enough to deal with instantiation of classes via factory methods. I seem to recall seeing this pattern a lot. To be extra sneaky I have my factory method return an instance of self
rather than referring to the class name. Looks like PHPStan isn't smart enough to recogize the undeclared property assignment.
file2.php
<?php
require_once 'foo2.php';
$foo = FooClass2::factory();
$foo->some_new_property = 42;
var_dump($foo);
foo2.php
<?php
require_once 'foo.php';
class FooClass2 extends FooClass {
// let's see if phpstan can detect factory methods
public static function factory(){
return new self();
}
}
The analysis doesn't catch the undeclared property assignment in file2.php. If you crank up the reporting level to 6, it does complain that you haven't declared a return type for the factory method in foo2.php:
$ vendor/bin/phpstan analyse -l 6 foo
4/4 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ---------------------------------------------------------------
Line file.php
------ ---------------------------------------------------------------
4 Access to an undefined property FooClass::$some_new_property.
------ ---------------------------------------------------------------
------ -----------------------------------------------------------
Line foo2.php
------ -----------------------------------------------------------
5 Method FooClass2::factory() has no return type specified.
------ -----------------------------------------------------------
[ERROR] Found 2 errors