You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Laravel嵌套Scope在PHPStan/LaraStan中的未定义方法警告?

解决Scope内部调用Scope时的PHPStan/LaraStan报错问题

核心原因

LaraStan默认能识别模型上的查询作用域,但在Scope闭包内部,$query参数会被默认推断为基础的Illuminate\Database\Eloquent\Builder类型,而非你的模型对应的专属Builder类,因此无法识别模型上定义的自定义作用域方法。

解决方案:添加精确类型提示

不需要使用@phpstan-ignore-next-line忽略警告,只需给Scope闭包里的$query参数指定精确类型即可,具体分两种场景:

场景1:使用自定义Builder类

如果你的模型定义了专属Builder类,直接将$query参数类型指定为该自定义类:

// App\Models\Post.php
namespace App\Models;

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

class Post extends Model
{
    // 返回自定义Builder实例
    public function newEloquentBuilder($query): PostBuilder
    {
        return new PostBuilder($query);
    }

    public function scopeActive(Builder $query): void
    {
        $query->where('is_active', true);
    }

    // 这里指定$query为PostBuilder类型
    public function scopePublished(PostBuilder $query): void
    {
        $query->active() // PHPStan可正常识别该方法
              ->where('published_at', '<=', now());
    }
}

// App\Models\PostBuilder.php
namespace App\Models;

use Illuminate\Database\Eloquent\Builder;

class PostBuilder extends Builder
{
    // 自定义Builder的扩展方法
}

场景2:无自定义Builder类

如果没有自定义Builder,给$query添加泛型类型注释,明确关联到当前模型:

// App\Models\Post.php
namespace App\Models;

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

class Post extends Model
{
    public function scopeActive(Builder $query): void
    {
        $query->where('is_active', true);
    }

    public function scopePublished(Builder $query): void
    {
        // 通过泛型注释明确$query属于Post模型的Builder
        /** @var Builder<Post> $query */
        $query->active() // 类型提示后PHPStan可识别方法
              ->where('published_at', '<=', now());
    }
}

额外说明

这种方式比忽略注释更严谨,既能解决PHPStan的警告,还能提升代码的类型安全性与可读性——LaraStan依赖精确的类型推断来关联模型的作用域方法,明确类型后就能正常识别自定义作用域。

内容的提问来源于stack exchange,提问作者Yevgeniy Afanasyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:47:10