修复 phpstan(或 larastan)的 Laravel 范围警告?

Yev*_*yev 5 laravel phpstan

使用 phpstan/larastan 分析代码时如何处理 Laravel 中的范围?

我收到此错误:

Call to an undefined method Illuminate\Database\Eloquent\Builder::active().
Run Code Online (Sandbox Code Playgroud)

我需要以某种方式输入提示吗?

我试图避免@phpstan-ignore-next-line

值得一提的是,仅当我在作用域内使用作用域时才会出现上述错误。在其他情况下,成功LaraStan阻止PhpStan警告。

Top*_*ter 6

在撰写本文时,存在三种方法。

但我在同一个项目中同时使用第一种和第三种方法,因为有许多 Composer 包不使用我的第二种或第三种方法。

第一种方法是一种解决方法

只需忽略 Laravel 在phpstan.neon文件中的“魔法”,例如:

parameters:
    paths:
        - app

    excludePaths:
        - ./vendor/**

    reportUnmatchedIgnoredErrors: false
    ignoreErrors:
        - '#Call to an undefined method#'
        - '#Call to an undefined static method#'
Run Code Online (Sandbox Code Playgroud)

笔记

您可以自定义上述正则表达式以仅忽略需要的内容。

但是PHP 不允许一个类有两次相同的名称:

PHP Fatal error:  Cannot redeclare App\Models\MyModel::active()
Run Code Online (Sandbox Code Playgroud)

虽然Laravel 的范围“magic”允许“静态”和“实例”上下文中使用相同的名称,例如:

$query = MyModel::active();
$query = MyModel::where('id', '!=', 1)->active();
Run Code Online (Sandbox Code Playgroud)

意思是,即使您使用文档注释,例如:

/**
 * @method static active()
 * @method active()
 */
class MyModel { ... }
Run Code Online (Sandbox Code Playgroud)

它只会将phpstan的消息更改为:

Static call to instance method App\Models\MyModel::active().
Run Code Online (Sandbox Code Playgroud)

第二种方法是解决方案

由于上述注释部分提到的原因;
在 Laravel 的“静态作用域魔法”的所有使用前面加上“query()->”前缀,例如更改为:

MyModel::active();
Run Code Online (Sandbox Code Playgroud)

进入:

MyModel::query()->active();
Run Code Online (Sandbox Code Playgroud)

最后,添加文档注释,例如:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

/**
 * @method Builder|static active()
 * @method static Builder|static query()
 */
class MyModel extends Model { ... }
Run Code Online (Sandbox Code Playgroud)

第三种方法是一个技巧

基本上,执行第二种方法所说的所有操作,
不要像大多数库那样使用文档注释,而是将范围方法与普通方法配对,该方法无需任何查询即可检查相同的字段,例如:

parameters:
    paths:
        - app

    excludePaths:
        - ./vendor/**

    reportUnmatchedIgnoredErrors: false
    ignoreErrors:
        - '#Call to an undefined method#'
        - '#Call to an undefined static method#'
Run Code Online (Sandbox Code Playgroud)

请注意,上面的技巧让 IDE 和phpstan认为->active() 可能返回Builder|static,这允许链接,例如:

$query = MyModel::query()
    ->active()
    ->where(...);
Run Code Online (Sandbox Code Playgroud)