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

Laravel 9中使用Spatie权限包时,getAllPermissions()结合where条件无法筛选指定前缀权限的问题咨询

解决Laravel Spatie权限包筛选前缀权限的问题

你遇到的问题核心是集合(Collection)的where方法和查询构造器(Query Builder)的where方法行为不一样,直接用like作为Collection的where参数是不生效的,因为Collection的where不支持SQL风格的like匹配,它默认做的是严格相等判断。

下面给你两种可行的解决方法:

方法一:在集合层面过滤(适合已获取所有权限后筛选)

利用Laravel的字符串辅助函数Str::startsWith来判断权限名称是否以指定前缀开头,结合集合的filter方法实现筛选:

use Illuminate\Support\Str;

// 匿名函数写法
auth()->user()->getAllPermissions()->filter(function ($permission) {
    return Str::startsWith($permission->name, 'admin_side_barmenu');
})->toArray();

// 更简洁的箭头函数写法(PHP 7.4+支持)
auth()->user()->getAllPermissions()->filter(fn($permission) => Str::startsWith($permission->name, 'admin_side_barmenu'))->toArray();

方法二:在数据库层面筛选(更高效,减少内存占用)

如果不需要先获取所有权限,直接在数据库查询时就过滤,这样性能更好,尤其当用户权限较多时:

如果要包含用户通过角色继承的权限,需要用Spatie提供的getAllPermissionsQuery()方法构建查询:

auth()->user()->getAllPermissionsQuery()
    ->where('name', 'like', 'admin_side_barmenu%')
    ->get()
    ->toArray();

如果只需要用户直接拥有的权限,也可以直接用关联关系查询:

auth()->user()->permissions()
    ->where('name', 'like', 'admin_side_barmenu%')
    ->get()
    ->toArray();

为什么你的原代码不生效?

auth()->user()->getAllPermissions()返回的是Illuminate\Database\Eloquent\Collection实例,它的where方法语法和Query Builder完全不同:

  • Query Builder的where('name', 'like', '%xxx%')是SQL层面的模糊匹配
  • Collection的where('name', 'like', '%xxx%')会把第三个参数当作比较运算符,但Collection只支持=, !=, <, >, <=, >=这些基础运算符,like并不在其中,所以它还是会执行严格相等判断,导致只有精确匹配名称的权限才会被筛选出来。

内容的提问来源于stack exchange,提问作者Ram Chander

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:07:38