grifart/phpstan-rules

填充PHP类型系统缺失的部分。

dev-master 2019-12-05 15:04 UTC

This package is auto-updated.

Last update: 2024-09-06 01:39:29 UTC


README

@overrides 或必须调用父类

如果存在覆盖方法,它必须具有注解 @overrides 或必须调用父类方法。

class BasePresenter {

  private $dep;

  public function injectFoo(Dependency $dep): void {
      $this->dep = $dep
  }

}

class LoginPresenter extends BasePresenter {

  private $dep;
  
  public function injectFoo(Dependency $dep): void {
      $this->dep = $dep
  }

}

需要 LoginPresenter 明确告诉你在覆盖方法

class LoginPresenter extends BasePresenter {

  private $dep;
  
  /**
   * @overrides
   */
  public function injectFoo(Dependency $dep): void {
      $this->dep = $dep
  }

}

或调用父函数

class LoginPresenter extends BasePresenter {

  private $dep;
  
  public function injectFoo(Dependency $dep): void {
      $this->dep = $dep
      parent::injectFoo($dep);
  }

}

密封类

密封类用于表示受限的类层次结构。

// file: enum.php

/**
 * @sealed
 */
abstract class EnumFoo {
}

final class Value1 extends EnumFoo {}
final class Value2 extends EnumFoo {}
final class Value3 extends EnumFoo {}

// file: other.php

final class Value4 extends EnumFoo {} // not allowed

这限制了声明任何其他 EnumFoo 的子类型,包括 Value1Value2Value3。这很有用,因为那时应该理解

\assert($value instanceof EnumFoo);

switch (getclass($value)): {
  case Value1::class:
    break;
  case Value2::class:
    break;
  case Value3::class:
    break;
  default:
    echo "unreachable code!";
    break;
}

类型系统应该知道默认情况是不可达的,因为不能在任何地方声明其他类型。

在子类中覆盖属性

class BasePresenter {

  /** @var Dependency */
  public $dep;

}

class LoginPresenter extends BasePresenter {

  /** @var Dependency2 */
  public $dep; // error

}

require_once 返回值被使用

这通常不是你预期的。