👨‍✈️

larastanの導入

2021/12/22に公開

larastan

Laravel用のphpstanです。

https://github.com/nunomaduro/larastan
https://blog.shin1x1.com/entry/getting-stated-with-phpstan

インストール

composer require nunomaduro/larastan --dev

検査コマンド:

./vendor/bin/phpstan analyse

設定ファイル

includes:
    - ./vendor/nunomaduro/larastan/extension.neon
parameters:
    paths:
        - app
        - bootstrap
        - config
        - database
        - routes
        - packages
    level: 0

実行結果(Level0)

# ./vendor/bin/phpstan analyse
Note: Using configuration file /usr/share/nginx/html/phpstan.neon.
 110/110 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ ----------------------------------------------------------------------- 
  Line   packages/Domain/Base/ValueObject/Enum.php                              
 ------ ----------------------------------------------------------------------- 
  29     Instantiated class Packages\Domain\Base\ValueObject\Enum is abstract.  
 ------ ----------------------------------------------------------------------- 

 ------ --------------------------- 
  Line   routes/console.php         
 ------ --------------------------- 
  18     Undefined variable: $this  
 ------ --------------------------- 

 -- ----------------------------------------------------------------------------------------------------- 
     Error                                                                                                
 -- ----------------------------------------------------------------------------------------------------- 
     Child process error (exit code 255):                                                                 
        Symfony\Component\ErrorHandler\Error\FatalError                                                   
                                                                                                          
       Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)                   
                                                                                                          
       at phar://vendor/phpstan/phpstan/phpstan.phar/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php:63  
          59▕         $count = \count($this->types);                                                      
          60▕         foreach ($tokens as &$match) {                                                      
          61▕             for ($i = 1; $i <= $count; $i++) {                                              
          62▕                 if ($match[$i] !== null && $match[$i] !== '') {                             
       ➜  63▕                     $match = [$match[0], $this->types[$i - 1]];                             
          64▕                     break;                                                                  
          65▕                 }                                                                           
          66▕             }                                                                               
          67▕         }                                                                                   
                                                                                                          
                                                                                                          
        Whoops\Exception\ErrorException                                                                   
                                                                                                          
       Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)                   
                                                                                                          
       at phar://vendor/phpstan/phpstan/phpstan.phar/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php:63  
          59▕         $count = \count($this->types);                                                      
          60▕         foreach ($tokens as &$match) {                                                      
          61▕             for ($i = 1; $i <= $count; $i++) {                                              
          62▕                 if ($match[$i] !== null && $match[$i] !== '') {                             
       ➜  63▕                     $match = [$match[0], $this->types[$i - 1]];                             
          64▕                     break;                                                                  
          65▕                 }                                                                           
          66▕             }                                                                               
          67▕         }                                                                                   
                                                                                                          
           +1 vendor frames                                                                               
       2   [internal]:0                                                                                   
           Whoops\Run::handleShutdown()                                                                   
                                                                                                          
     Child process error (exit code 255):                                                                 
 -- ----------------------------------------------------------------------------------------------------- 

                                                                                                                        
 [ERROR] Found 4 errors

Instantiated class Packages\Domain\Base\ValueObject\Enum is abstract.

Packages\Domain\Base\ValueObject\Enumが抽象クラス(abstract)なのですが
それをインスタンス化(new)した為に起きた警告と思われます。
(get_called_classで継承したクラス名を取得して、それをインスタンス化しているはずなので
 Enum自体がインスタンス化されることはない気がしますが、larastanでの検査ではそのように認識されてしまうのか?よく分からなかったです)

    final public static function __callStatic($label, $args)
    {
        $class = get_called_class();
        $const = constant("$class::$label");
        return new $class($const);
    }

こちらはenumを自前で用意していたので「laravel-enum」に置き換え
https://speakerdeck.com/twada/php-conference-2016?slide=40

Class Packages\Domain\Novel\ValueObject\APIParametor\UserId does not have a constructor and must be instantiated without any parameters.

__constructのtypoが原因だった...。これまでなぜエラーにならなかったのか謎。

Access to an undefined property Packages\Domain\Novel\Entity\NovelAPIParametorEntity::$user_id.

クラスのプロパティにアクセスできないために警告がでています。
これはこのプロパティが存在しなかった為、プロパティを追加しました。

routes/console.phpでのUndefined variable: $this

 ------ --------------------------- 
  Line   routes/console.php         
 ------ --------------------------- 
  18     Undefined variable: $this  
 ------ ---------------------------

クロージャ内での$thisの誤検知は現状対応する術がないぽい。
excludePathsでチェックから外すようにしました。
https://github.com/nunomaduro/larastan/issues/140

Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)

メモリエラーになる場合は「memory-limit」オプションを指定する

./vendor/bin/phpstan analyse --memory-limit=1G

実行結果(Level1)

Variable $urlList might not be defined.

変数が定義(初期化)されていない為に警告がでていた。

実行結果(Level2)

Result of method Packages\Infrastructure\Repositories\ScopperSokuhouRecommendScrapingRepository::execute()

     (void) is used.

返り値がなにもないがreturn している為エラーになっている。retrunを外して対応

Discussion