Various PHPStan rules we found useful in ShipMonk.

Overview

ShipMonk PHPStan rules

Various rules we found useful in ShipMonk. You may found some of them opinionated, so we recommend picking only those fitting your needs. If you would like to use all of them anyway, use:

includes:
    - vendor/shipmonk/phpstan-rules/rules.neon

Installation:

composer require shipmonk/phpstan-rules

Rules:

All you need to enable most of the rules is to register them as documented in phpstan/phpstan. Some of them need some specific rich parser node visitor to be registered as well. Rarely, some rules are reliable only when some other rule is enabled.

AllowNamedArgumentOnlyInAttributesRule

  • Allows usage of named arguments only in native attributes
  • Before native attributes, we used DisallowNamedArguments. But we used Doctrine annotations, which almost "require" named arguments when converted to native attributes.
  • Requires NamedArgumentSourceVisitor to work
rules:
    - ShipMonk\PHPStan\Rule\AllowNamedArgumentOnlyInAttributesRule
services:
    -
    class: ShipMonk\PHPStan\Visitor\NamedArgumentSourceVisitor
    tags:
        - phpstan.parser.richParserNodeVisitor
class User {
    #[Column(type: Types::STRING, nullable: false)] // allowed
    private string $email;

    public function __construct(string $email) {
        $this->setEmail(email: $email); // forbidden
    }
}

ForbidFetchOnMixedRule

  • Denies property fetch on unknown type.
  • Any property fetch assumes the caller is an object with such property and therefore, the typehint/phpdoc should be fixed.
  • Similar to ForbidMethodCallOnMixedRule
rules:
    - ShipMonk\PHPStan\Rule\ForbidFetchOnMixedRule
function example($unknown) {
    $unknown->property; // cannot fetch property on mixed
}

ForbidMatchDefaultArmForEnumsRule

  • Denies using default arm in match() construct when native enum is passed as subject
  • This rules makes sense only as a complement of native phpstan rule that guards that all enum cases are handled in match arms
  • As a result, you are forced to add new arm when new enum case is added
rules:
    - ShipMonk\PHPStan\Rule\ForbidFetchOnMixedRule
match ($enum) {
    MyEnum::Case: 1;
    default: 2; // default arm forbidden
}

ForbidMethodCallOnMixedRule

  • Denies calling methods on unknown type.
  • Any method call assumes the caller is an object with such method and therefore, the typehint/phpdoc should be fixed.
  • Similar to ForbidFetchOnMixedRule
rules:
    - ShipMonk\PHPStan\Rule\ForbidMethodCallOnMixedRule
function example($unknown) {
    $unknown->call(); // cannot call method on mixed
}

ForbidUnsetClassFieldRule

  • Denies calling unset over class field as it causes un-initialization, see https://3v4l.org/V8uuP
  • Null assignment should be used instead
rules:
    - ShipMonk\PHPStan\Rule\ForbidUnsetClassFieldRule
function example(MyClass $class) {
    unset($class->field); // denied
}

ForbidUselessNullableReturnRule

  • Denies marking method return type as nullable when null is never returned
  • Recommended to be used together with UselessPrivatePropertyDefaultValueRule and UselessPrivatePropertyNullabilityRule
rules:
    - ShipMonk\PHPStan\Rule\ForbidUselessNullableReturnRule
class Example {
    public function example(int $foo): ?int { // null never returned
        if ($foo < 0) {
            return 0;
        }
        return $foo;
    }
}

ForbidUnusedExceptionRule

  • Reports forgotten exception throw (created or returned from function, but not used in any way)
  • Requires UnusedExceptionVisitor to work
rules:
    - ShipMonk\PHPStan\Rule\ForbidUnusedExceptionRule
services:
    -
    class: ShipMonk\PHPStan\Visitor\UnusedExceptionVisitor
    tags:
        - phpstan.parser.richParserNodeVisitor
function validate(): void {
    new Exception(); // forgotten throw
}

RequirePreviousExceptionPassRule

  • Detects forgotten exception pass-as-previous when re-throwing
  • Checks if caught exception can be passed as argument to the call (including constructor call) in throw node inside the catch block
  • You may encounter false-positives in some edge-cases, where you do not want to pass exception as previous, feel free to ignore those
rules:
    - ShipMonk\PHPStan\Rule\RequirePreviousExceptionPassRule
try {
    // some code
} catch (RuntimeException $e) {
    throw new LogicException('Cannot happen'); // $e not passed as previous
}

UselessPrivatePropertyDefaultValueRule:

  • Detects useless default value of a private property that is always initialized in constructor.
  • Cannot handle conditions or private method calls within constructor.
  • Requires TopLevelConstructorPropertyFetchMarkingVisitor to work
  • Should be used together with ForbidReturnInConstructorRule to avoid false positives when return statement is used in constructor
  • Recommended to be used with UselessPrivatePropertyNullabilityRule and ForbidUselessNullableReturnRule
rules:
    - ShipMonk\PHPStan\Rule\UselessPrivatePropertyDefaultValueRule
    - ShipMonk\PHPStan\Rule\ForbidReturnInConstructorRule
services:
    -
    class: ShipMonk\PHPStan\Visitor\TopLevelConstructorPropertyFetchMarkingVisitor
    tags:
        - phpstan.parser.richParserNodeVisitor
class Example
{
    private ?int $field = null; // useless default value

    public function __construct()
    {
        $this->field = 1;
    }
}

UselessPrivatePropertyNullabilityRule:

  • Detects useless nullability of a private property by checking type of all assignments.
  • Requires ClassPropertyAssignmentVisitor to work
  • Recommended to be used with UselessPrivatePropertyNullabilityRule and ForbidUselessNullableReturnRule as removing useless default value may cause useless nullability to be detected
rules:
    - ShipMonk\PHPStan\Rule\UselessPrivatePropertyNullabilityRule
services:
    -
    class: ShipMonk\PHPStan\Visitor\ClassPropertyAssignmentVisitor
    tags:
        - phpstan.parser.richParserNodeVisitor
class Example
{
    private ?int $field; // useless nullability

    public function __construct()
    {
        $this->field = 1;
    }

    public function setField(int $value)
    {
        $this->field = $value;
    }
}
Comments
  • Current release broken ?

    Current release broken ?

    I need to remove both ForbidMethodCallOnMixedRule and ForbidFetchOnMixedRule from neon.rules in order to make it work.

    I think I already stumbled upon a commit that solves this.

    JFYI :)

    Thank you & great work!

    opened by ilazaridis 3
  • ForbidAssignmentNotMatchingVarDocRule  - allow type narrowing

    ForbidAssignmentNotMatchingVarDocRule - allow type narrowing

    I like ForbidAssignmentNotMatchingVarDocRule rule but in our codebase we often use @var comments to specify narrower type not properly detected by PHPStan. Would you welcome PR with configuration option that would allow type narrowing for this rule?

    opened by MartinMystikJonas 2
  • EnforceNativeReturnTypehintRule: resource not typehintable & fix self|self

    EnforceNativeReturnTypehintRule: resource not typehintable & fix self|self

    • No type hint for resources is added, as this would prevent moving from resources to objects for existing extensions, which some have already done (e.g. GMP).
      • https://wiki.php.net/rfc/scalar_type_hints
    opened by janedbal 0
  • Match can contain only assignments

    Match can contain only assignments

    Match can contain only assignments like this:

            match ($int) {
                0 => $a = 'x',
                1 => $b = 'y',
            };
    

    Then is not necessary to trigger ForbidUnusedMatchResultRule.

    opened by MilanPala 0
  • Replace rule+visitor DIC registration by config

    Replace rule+visitor DIC registration by config

    • possibly targets 2.0.0
    • allows doing https://github.com/shipmonk-rnd/phpstan-rules/pull/38 without any BC
    • simplifies readme and one-by-one enable/disable usage
    • supersedes https://github.com/shipmonk-rnd/phpstan-rules/pull/37 idea
    opened by janedbal 0
  • EnforceNativeReturnTypehintRule: try narrowing enforcement

    EnforceNativeReturnTypehintRule: try narrowing enforcement

    • attempt, but when tested on big codebase, there are plenty problematic situations, like
      • typehint says interface, but we return multiple children -> forcing to use union of them
      • anon classes returned (fixable)
      • invalid (old) phpdocs like Generator|mixed[] breaking proper suggestion -> forcing generinc iterable in this example
      • invalid phpdocs (this is not reported by phpstan) like this -> forcing wrong native typehint
    opened by janedbal 0
Releases(2.0.1)
  • 2.0.1(Dec 2, 2022)

    Fixes:

    • uselessPrivatePropertyNullability: fix false positive within promoted properties (https://github.com/shipmonk-rnd/phpstan-rules/pull/55, thx @enumag)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Nov 15, 2022)

    Major changes :tada:

    • Much easier setup. Just include vendor/shipmonk/phpstan-rules/rules.neon in your codebase; no need to register all rules, visitors and tags as before (https://github.com/shipmonk-rnd/phpstan-rules/pull/44)
      • Also, you can easily enable/disable rules one by one like this:
    includes:
        - vendor/shipmonk/phpstan-rules/rules.neon
    
    parameters:
        shipmonkRules:
            allowNamedArgumentOnlyInAttributes:
                enabled: false
    

    New features

    Improvements

    • ForbidFetchOnMixedRule and ForbidMethodCallOnMixedRule does not make sense on level9, so it gets autodisabled in that case (https://github.com/shipmonk-rnd/phpstan-rules/pull/38)

    Error message changes

    • ForbidAssignmentNotMatchingVarDocRule now reports type narrowing with different message (https://github.com/shipmonk-rnd/phpstan-rules/pull/45)
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Oct 10, 2022)

    New features

    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Aug 20, 2022)

  • 1.1.0(Aug 17, 2022)

    New features:

    Dependencies

    • phpstan/phpstan now requires at least 1.8.1 (https://github.com/shipmonk-rnd/phpstan-rules/pull/15)

    Deprecations

    • using rules.neon is discouraged and the file will be removed in next major version, new rules are not added anymore there
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Jun 24, 2022)

    Fixes:

    • Use reliable static reflection concepts, no is_a inside rules (https://github.com/shipmonk-rnd/phpstan-rules/pull/10)
      • Checked since phpstan 1.7.15, needed since phpstan onboarded fully static reflection (1.7.0)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Jun 24, 2022)

Owner
ShipMonk R&D
ShipMonk Research & Development
ShipMonk R&D
Custom PHPStan rules

phpstan-rules Provides additional rules for phpstan/phpstan. Installation Run $ composer require --dev alister/phpstan-rules Usage All of the rules pr

Alister Bulman 1 Nov 4, 2021
Repository containing all the PHPStan rules from the book "Recipes for Decoupling"

PHPStan rules from the book "Recipes for Decoupling" by Matthias Noback In the book "Recipes for Decoupling" we discuss how to decouple from web and C

Matthias Noback 19 Sep 21, 2022
Phpcs-magento-rules - A set of PHPCS rules used by made.com when hacking Magento

Made.com PHPCS Magento Rules A set of PHPCS rules used by made.com when hacking Magento. Pre-Requisites PHPCS Installation Short Version Clone this re

Made.com Tech Team 26 Jun 3, 2020
[READ-ONLY] CakePHP Utility classes such as Inflector, Text, Hash, Security and Xml. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Utility Classes This library provides a range of utility classes that are used throughout the CakePHP framework What's in the toolbox? Hash A

CakePHP 112 Feb 15, 2022
Hi Im L, I found a box that I believe it's contain Kira's real ID. for open that box we need to find three keys. let's start looking for them

DeathNote ctf Description are you smart enaugh to help me capturing the three keys for open the box that contain the real ID of kira? Let's start solv

Hamza Elansari 4 Nov 28, 2022
Magento 2 Module Experius Page Not Found 404. This module saves all 404 url to a database table

Magento 2 Module Experius Page Not Found 404 This module saves all 404 urls to a database table. Adds an admin grid with 404s It includes a count so y

Experius 28 Dec 9, 2022
This project backports features found in the latest PHP versions and provides compatibility layers for some extensions and functions

This project backports features found in the latest PHP versions and provides compatibility layers for some extensions and functions. It is intended to be used when portability across PHP versions and extensions is desired.

Symfony 2.2k Dec 29, 2022
PHPStan extension to support #[Readonly] constructor properties

icanhazstring/phpstan-readonly-property Support #[Readonly] promoted constructor properties for PHPStan. This library is used to have a full transitio

Andreas Frömer 4 Apr 5, 2022
Analyzes PHPStan baseline files and creates aggregated error trend-reports

Analyzes phpstan baseline files Analyzes PHPStan baseline files and creates aggregated error trend-reports.

Markus Staab 22 Dec 23, 2022
Magento specific extension for phpstan

bitexpert/phpstan-magento This package provides some additional features for PHPStan to make it work for Magento 2 projects. Installation The preferre

bitExpert AG 92 Dec 7, 2022
Sandbox project for the PHPStan workshop

Sandbox project for a PHPStan workshop Installation Requirements Docker Engine Docker Compose Git Bash Getting started Clone this repository (git clon

Matthias Noback 4 Oct 17, 2022
A PHPStan package that supports working with Extbase

PHPStan for Extbase This package provides a couple of stubs and services to make your life easier when working with PHPStan and Extbase. Examples clas

Alexander Schnitzler 7 Dec 10, 2021
The main scope of this extension is to help phpstan to detect the type of object after the Assert\Assertion validation.

PHPStan beberlei/assert extension PHPStan beberlei/assert Description The main scope of this extension is to help phpstan to detect the type of object

PHPStan 33 Jan 2, 2023
Doctrine extensions for PHPStan

Doctrine extensions for PHPStan PHPStan Doctrine This extension provides following features: DQL validation for parse errors, unknown entity classes a

PHPStan 478 Jan 3, 2023
PHPStan extension for webmozart/assert

PHPStan webmozart/assert extension PHPStan webmozart/assert Description The main scope of this extension is to help phpstan to detect the type of obje

PHPStan 139 Dec 22, 2022
An extension for PHPStan for adding analysis for PHP Language Extensions.

PHPStan PHP Language Extensions (currently in BETA) This is an extension for PHPStan for adding analysis for PHP Language Extensions. Language feature

Dave Liddament 9 Nov 30, 2022
PHPStan extension for sealed classes and interfaces.

Sealed classes with PHPStan This extension adds support for sealed classes and interfaces to PHPStan. Installation To use this extension, require it v

Jiří Pudil 14 Nov 28, 2022
Extension for PHPStan to allow analysis of Drupal code.

phpstan-drupal Extension for PHPStan to allow analysis of Drupal code. Sponsors Would you like to sponsor? Usage When you are using phpstan/extension-

Matt Glaman 154 Jan 2, 2023
WordPress extensions for PHPStan ⛏️

WordPress extensions for PHPStan Static analysis for the WordPress ecosystem. PHPStan WordPress Installation Add this package to your project. compose

Viktor Szépe 183 Dec 30, 2022