Benjamin Cremer
@benjamincremer
Once a month. Speakers wanted!
meetup.com/phpugms
@phpugms
public function addNumbers(float $a, $float $b): float
{
return $a - $b;
}
function foo() {
bar()
$baz
}
# Run PHP Syntax check (lint)
$ php -l example.php
PHP Parse error: syntax error, unexpected '$baz' (T_VARIABLE) in example.php
on line 4
Errors parsing syntax-error.php
# "compile" code
# Syntax errors are also compile-time errors
$ php example.php
PHP Parse error: syntax error, unexpected '$baz' (T_VARIABLE) in example.php on line 4
Syntax Check with PHP Parallel Lint
Wrapper around php -l with several options for your convenience. checks your files in parallel making use of your multiple-core machines.
interface Car
{
public function drive(): int;
}
class Tesla implements Car
{
public function drive(): string
{
return 'fasel';
}
}
$ php -l example.php
No syntax errors detected in example.php
$ php example.php
PHP Fatal error: Declaration of Tesla::drive(): string must
be compatible with Car::drive(): int in example.php on line 8
class Car
{
public function drive(): void {}
}
function testdrive(Car $car) {
$car->fly();
}
$ php -l example.php
No syntax errors detected in example.php
$ php example.php
(Exit code: 0)
class Car
{
public function drive(): void {}
}
function testdrive(Car $car) {
$car->fly();
}
testdrive(new Car()); // execute above code
$ php example.php
PHP Fatal error: Uncaught Error: Call to undefined method Car::fly()
in example.php:9
class Car
{
public function drive(): void {}
}
function testdrive(Car $car, bool $fly) {
if ($fly) {
$car->fly();
} else {
$car->drive();
}
}
testdrive(new Car(), false); // works just fine
testdrive(new Car(), true); // kaboom
A talk by Gary Bernhardt from Strange Loop 2015
destroyallsoftware.com/talks/ideologyPredict the behavior of software without running it.
Promote runtime errors to compile time error.
Find Bugs In Your Code Without Writing Tests!
Inferring types when types are not given.
function addStrings($part1, $part2)
{
// concat operation always yields a string
return $part1 . $part2;
}
// $foo can be inferred as string
$foo = addStrings($unknownA, $unknownB);
/**
* @param DateTimeInterface $dateTime
* @param int $days
* @return \DateTimeInterface
*/
function addDays($dateTime, $days) {
[...]
}
function addDays(
\DateTimeInterface $dateTime,
int $days
): \DateTimeInterface {
[...]
}
/**
* @return string[]
*/
function getDaysOfWeek(): array {
return [
'monday',
'tuesday',
[...]
];
}
/**
* @return array<int, string>
*/
function getDaysOfWeek(): array {
return [
'monday',
'tuesday',
[...]
];
}
/**
* @method Booking|null findOneByUuid(string $uuid)
* @method Booking[] findByUuid(string $uuid)
*/
class BookingRepository extends EntityRepository
{
}
/** @var \DateTimeInterfa
ce $date */
$date = Thirdparty::createDate();
$date = Thirdparty::createDate();
assert($date instanceof \DateTimeInterface);
via: https://github.com/doctrine/coding-standard/pull/47
PHP-CS-Fixer and PHP_CodeSniffer can assist you with that
php composer require --dev doctrine/coding-standard
nikic/php-parser by Nikita Popov
A PHP parser written in PHP
nikic/php-ast by Nikita Popov
Extension that exposes the abstract syntax tree generated by PHP 7
php composer require nikic/php-parser
./vendor/bin/php-parse src/ast_example.php
Not very CI friendly
yes, there is a inspection.sh, but no
vimeo/psalm | phan/phan | phpstan/phpstan | |
---|---|---|---|
Author | Vimeo | Rasmus Lerdorf | Ondřej Mirtes |
PHP Version | >= 5.6 | >= 7.0 | >= 7.1 |
AST | PHP-Parser | ext-ast | PHP-Parser |
And so much more: https://github.com/exakat/php-static-analysis-tools
composer require --dev phpstan/phpstan
./vendor/bin/phpstan analyse -l3 src/
docker run --rm -v $PWD:/app phpstan/phpstan analyse -l3 /app/src/
namespace Example;
class Testdriver
{
public static function testdrive(Car $car, bool $fly)
{
if ($fly) {
$car->fly();
} else {
$car->drive();
}
}
}
$ ./vendor/bin/phpstan analyse -l3 src/Testdriver.php
1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ -------------------------------------------------
Line Testdriver.php
------ -------------------------------------------------
9 Call to an undefined method Example\Car::fly().
------ -------------------------------------------------
[ERROR] Found 1 error
Please leave feedback