pkc/role-permission
Composer 安装命令:
composer require pkc/role-permission
包简介
A dynamic role and permission management package for Laravel.
README 文档
README
A lightweight, dynamic role and permission management package for Laravel. This package allows you to manage roles and permissions dynamically via the database, with support for hierarchical permissions and granular access control.
✨ Features
- 🔐 Dynamic Roles & Permissions: Store and manage roles and permissions in the database
- 🌳 Hierarchical Permissions: Supports parent-child relationships for permissions (e.g., a "Module" permission containing multiple "Action" permissions)
- ⚡ Performance Optimized: Built-in caching support for faster permission checks
- 🚀 Easy Integration: Simple traits for
UserandRolemodels - 🎯 Route Access Control: Helpers to check access based on route names
- 🔒 Production Ready: Validation, error handling, and security features
📋 Requirements
- PHP >= 8.2
- Laravel >= 11.0
- Composer
📦 Installation
You can install the package via composer:
composer require pkc/role-permission
🔧 Setup
1. Publish Configuration (Optional)
php artisan vendor:publish --tag=role-permission-config
This will create config/role-permission.php where you can customize settings.
2. Run Migrations
The package comes with migrations for roles, permissions, and the pivot role_permissions table. Run them using:
php artisan migrate
3. Prepare your Models
User Model
Add the HasRoles trait to your User model:
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Pkc\RolePermission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; // Your existing code... }
Make sure your users table has a role_id foreign key column.
Role Model (Optional)
If you want to extend or customize the Role model:
namespace App\Models; use Pkc\RolePermission\Models\Role as BaseRole; class Role extends BaseRole { // Your custom logic here }
💡 Complete Example Flow
Here's a complete step-by-step example of setting up and using the package in a blog application:
Step 1: Setup and Migration
# Install the package composer require pkc/role-permission # Run migrations php artisan migrate
Step 2: Configure User Model
// app/Models/User.php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Pkc\RolePermission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; // Your existing code... }
Step 3: Create Roles
use Pkc\RolePermission\Models\Role; // Create roles $admin = Role::create([ 'name' => 'Administrator', 'slug' => 'admin', 'description' => 'Full system access', 'status' => true, ]); $editor = Role::create([ 'name' => 'Editor', 'slug' => 'editor', 'description' => 'Can create and edit posts', 'status' => true, ]); $author = Role::create([ 'name' => 'Author', 'slug' => 'author', 'description' => 'Can create posts', 'status' => true, ]);
Step 4: Create Permissions (Hierarchical Structure)
use Pkc\RolePermission\Models\Permission; // Create Posts Module (parent permission) $postsModule = Permission::create([ 'name' => 'Posts', 'slug' => 'posts', 'type' => 'module', 'route_name' => 'posts.index', 'order' => 1, 'status' => true, ]); // Create action permissions (children) $viewPosts = Permission::create([ 'name' => 'View Posts', 'slug' => 'posts.view', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.show', 'order' => 1, 'status' => true, ]); $createPosts = Permission::create([ 'name' => 'Create Posts', 'slug' => 'posts.create', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.create', 'order' => 2, 'status' => true, ]); $editPosts = Permission::create([ 'name' => 'Edit Posts', 'slug' => 'posts.edit', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.edit', 'order' => 3, 'status' => true, ]); $deletePosts = Permission::create([ 'name' => 'Delete Posts', 'slug' => 'posts.delete', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.destroy', 'order' => 4, 'status' => true, ]);
Step 5: Assign Permissions to Roles
// Admin gets all permissions $admin->syncPermissions([ $postsModule->id, $viewPosts->id, $createPosts->id, $editPosts->id, $deletePosts->id, ]); // Editor can view, create, and edit (but not delete) $editor->syncPermissions([ $viewPosts->id, $createPosts->id, $editPosts->id, ]); // Author can only view and create $author->syncPermissions([ $viewPosts->id, $createPosts->id, ]);
Step 6: Assign Roles to Users
use App\Models\User; // Assign admin role to a user $user1 = User::find(1); $user1->update(['role_id' => $admin->id]); // Assign editor role $user2 = User::find(2); $user2->update(['role_id' => $editor->id]); // Assign author role $user3 = User::find(3); $user3->update(['role_id' => $author->id]);
Step 7: Use in Controller
// app/Http/Controllers/PostController.php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class PostController extends Controller { public function index() { // Check permission if (!auth()->user()->hasPermission('posts.view')) { abort(403, 'You do not have permission to view posts.'); } $posts = Post::all(); return view('posts.index', compact('posts')); } public function create() { if (!auth()->user()->hasPermission('posts.create')) { abort(403); } return view('posts.create'); } public function store(Request $request) { if (!auth()->user()->canAccessRoute('posts.create')) { abort(403); } // Create post logic... } public function edit($id) { if (!auth()->user()->hasPermission('posts.edit')) { abort(403); } $post = Post::findOrFail($id); return view('posts.edit', compact('post')); } public function destroy($id) { if (!auth()->user()->hasPermission('posts.delete')) { abort(403); } // Delete post logic... } }
Step 8: Use in Blade Templates
{{-- resources/views/posts/index.blade.php --}} {{-- Show posts menu if user has posts permission --}} @if(auth()->user()->hasPermission('posts')) <li><a href="{{ route('posts.index') }}">Posts</a></li> @endif {{-- Show create button if user has create permission --}} @if(auth()->user()->hasPermission('posts.create')) <a href="{{ route('posts.create') }}" class="btn btn-primary">Create Post</a> @endif <table> @foreach($posts as $post) <tr> <td>{{ $post->title }}</td> <td> {{-- Show edit button if user has edit permission --}} @if(auth()->user()->hasPermission('posts.edit')) <a href="{{ route('posts.edit', $post) }}">Edit</a> @endif {{-- Show delete button if user has delete permission --}} @if(auth()->user()->hasPermission('posts.delete')) <form action="{{ route('posts.destroy', $post) }}" method="POST"> @csrf @method('DELETE') <button type="submit">Delete</button> </form> @endif </td> </tr> @endforeach </table>
Step 9: Testing the Flow
// Example: Testing permissions $user = User::find(2); // Editor user // These will return true $user->hasPermission('posts.view'); // true $user->hasPermission('posts.create'); // true $user->hasPermission('posts.edit'); // true $user->hasPermission('posts'); // true (parent module) // This will return false $user->hasPermission('posts.delete'); // false // Check role $user->hasRole('editor'); // true $user->hasAnyRole(['admin', 'editor']); // true // Check multiple permissions $user->hasAnyPermission(['posts.edit', 'posts.delete']); // true (has edit) $user->hasAllPermissions(['posts.edit', 'posts.delete']); // false (missing delete)
Step 10: Dynamic Permission Management (Optional)
You can also manage permissions dynamically through your admin panel:
// In your admin controller public function updateRolePermissions(Request $request, Role $role) { $permissionIds = $request->input('permissions', []); // Validate permission IDs exist $validIds = Permission::whereIn('id', $permissionIds)->pluck('id')->toArray(); // Sync permissions $role->syncPermissions($validIds); // Clear cache $role->clearPermissionCache(); return redirect()->back()->with('success', 'Permissions updated successfully'); }
This complete flow demonstrates:
- ✅ Setting up the package
- ✅ Creating roles and permissions
- ✅ Building hierarchical permission structure
- ✅ Assigning permissions to roles
- ✅ Assigning roles to users
- ✅ Using permissions in controllers
- ✅ Using permissions in Blade templates
- ✅ Testing and verification
💡 Usage Examples
Creating Roles
use Pkc\RolePermission\Models\Role; // Create a new role $adminRole = Role::create([ 'name' => 'Administrator', 'slug' => 'admin', 'description' => 'Full system access', 'status' => true, ]); $editorRole = Role::create([ 'name' => 'Editor', 'slug' => 'editor', 'description' => 'Can edit content', 'status' => true, ]);
Creating Permissions
use Pkc\RolePermission\Models\Permission; // Create a parent permission (module) $postsModule = Permission::create([ 'name' => 'Posts Management', 'slug' => 'posts', 'type' => 'module', 'route_name' => 'posts.index', 'order' => 1, 'status' => true, ]); // Create child permissions (actions) $viewPosts = Permission::create([ 'name' => 'View Posts', 'slug' => 'posts.view', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.show', 'order' => 1, 'status' => true, ]); $editPosts = Permission::create([ 'name' => 'Edit Posts', 'slug' => 'posts.edit', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.edit', 'order' => 2, 'status' => true, ]); $deletePosts = Permission::create([ 'name' => 'Delete Posts', 'slug' => 'posts.delete', 'type' => 'action', 'parent_id' => $postsModule->id, 'route_name' => 'posts.destroy', 'order' => 3, 'status' => true, ]);
Assigning Roles to Users
$user = User::find(1); $user->role_id = $adminRole->id; $user->save(); // Or using update $user->update(['role_id' => $editorRole->id]);
Assigning Permissions to Roles
$editorRole = Role::find(2); // Sync permissions (replaces all existing permissions) $editorRole->permissions()->sync([$viewPosts->id, $editPosts->id]); // Or use the helper method $editorRole->syncPermissions([$viewPosts->id, $editPosts->id]);
Checking Permissions in Code
// Check if user has a specific permission if ($user->hasPermission('posts.edit')) { // User can edit posts } // Check if user can access a route if ($user->canAccessRoute('posts.edit')) { // User can access this route } // Check if user has any of the given permissions if ($user->hasAnyPermission(['posts.edit', 'posts.view'])) { // User has at least one permission } // Check if user has all of the given permissions if ($user->hasAllPermissions(['posts.edit', 'posts.delete'])) { // User has all permissions } // Check if user has a specific role if ($user->hasRole('admin')) { // User is an admin } // Check if user has any of the given roles if ($user->hasAnyRole(['admin', 'editor'])) { // User has at least one role }
Using in Blade Templates
{{-- Check permission --}} @if(auth()->user()->hasPermission('posts.edit')) <a href="{{ route('posts.edit', $post) }}">Edit</a> @endif {{-- Check route access --}} @if(auth()->user()->canAccessRoute('posts.index')) <a href="{{ route('posts.index') }}">All Posts</a> @endif {{-- Check multiple permissions --}} @if(auth()->user()->hasAnyPermission(['posts.edit', 'posts.delete'])) <div class="actions"> <a href="{{ route('posts.edit', $post) }}">Edit</a> <a href="{{ route('posts.delete', $post) }}">Delete</a> </div> @endif {{-- Show sidebar menu based on permission --}} @if(auth()->user()->hasPermission('posts')) <li><a href="{{ route('posts.index') }}">Posts</a></li> @endif
Using in Controllers
namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class PostController extends Controller { public function index() { // Check permission if (!auth()->user()->hasPermission('posts.view')) { abort(403, 'You do not have permission to view posts.'); } // Your code... } public function edit($id) { if (!auth()->user()->canAccessRoute('posts.edit')) { abort(403); } // Your code... } }
Using in Middleware
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class CheckPermission { public function handle(Request $request, Closure $next, $permission) { if (!auth()->user()->hasPermission($permission)) { abort(403, 'Access denied'); } return $next($request); } }
Register in bootstrap/app.php:
$middleware->alias([ 'permission' => \App\Http\Middleware\CheckPermission::class, ]);
Use in routes:
Route::get('/posts', [PostController::class, 'index'])->middleware('permission:posts.view');
Hierarchical Permissions
The package supports hierarchical permissions. If a permission is a "module" type and has children, checking the parent permission will return true if any of its children are assigned to the role.
// If 'posts' is a module and 'posts.edit' is assigned to the role $user->hasPermission('posts'); // returns true (because descendant 'posts.edit' is assigned) $user->hasPermission('posts.edit'); // returns true (directly assigned) // This is useful for sidebar visibility // If user has access to any action within a module, the module appears in the sidebar
Querying Roles and Permissions
use Pkc\RolePermission\Models\Role; use Pkc\RolePermission\Models\Permission; // Get only active roles (excludes master-admin by default) $roles = Role::visible()->active()->get(); // Get root permissions (no parent) $rootPermissions = Permission::root()->get(); // Get only active permissions $activePermissions = Permission::active()->get(); // Get permissions with their children $permissions = Permission::root()->with('children')->get();
Cache Management
Permission checks are cached by default for better performance. To clear cache:
// Clear cache for a specific role $role->clearPermissionCache(); // Or clear all cache php artisan cache:clear
You can configure caching in config/role-permission.php:
'cache_enabled' => true, 'cache_ttl' => 3600, // Cache for 1 hour
🔒 Security Features
- Validation: Permission assignments are validated before saving
- Circular Reference Prevention: Automatic detection and prevention of circular permission hierarchies
- Error Handling: Proper exceptions for better error handling
📝 Configuration
You can customize the package behavior by publishing the config file:
php artisan vendor:publish --tag=role-permission-config
Available configuration options:
user_model: Your User model classmaster_admin_slug: Slug for master admin role (default: 'master-admin')cache_enabled: Enable/disable caching (default: true)cache_ttl: Cache time-to-live in seconds (default: 3600)table_names: Custom table names (optional)
🐛 Error Handling
The package provides specific exceptions:
use Pkc\RolePermission\Exceptions\CircularReferenceException; use Pkc\RolePermission\Exceptions\InvalidPermissionAssignmentException; use Pkc\RolePermission\Exceptions\PermissionNotFoundException; try { $role->syncPermissions([1, 2, 3]); } catch (InvalidPermissionAssignmentException $e) { // Handle invalid permission IDs }
📚 API Reference
User Model Methods (HasRoles trait)
hasPermission(string $slug): bool- Check if user has a permissioncanAccessRoute(string $routeName): bool- Check if user can access a routehasAnyPermission(array $slugs): bool- Check if user has any of the given permissionshasAllPermissions(array $slugs): bool- Check if user has all of the given permissionshasRole(string $slug): bool- Check if user has a specific rolehasAnyRole(array $slugs): bool- Check if user has any of the given rolesrole(): BelongsTo- Get the user's role relationship
Role Model Methods
hasPermission(string $slug): bool- Check if role has a permissionpermissions(): BelongsToMany- Get permissions relationshipsyncPermissions(array $permissionIds, bool $recursive = false): void- Sync permissionsclearPermissionCache(): void- Clear permission cache for this roleisMasterAdmin(): bool- Check if role is master adminscopeVisible($query)- Exclude master admin from queriesscopeActive($query)- Get only active roles
Permission Model Methods
parent(): BelongsTo- Get parent permissionchildren(): HasMany- Get child permissionsgetAllDescendantIds(): array- Get all descendant permission IDsgetAncestors(): Collection- Get all ancestor permissionstoTreeArray(): array- Get permission as tree structurescopeRoot($query)- Get only root permissionsscopeActive($query)- Get only active permissions
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
The MIT License (MIT). Please see License File for more information.
👤 Author
PKC
- Email: laradev.sumon@gmail.com
📊 Hierarchical Permission Structure Example
Here's an example of a real-world hierarchical permission structure:
FMDF
├── Stock Management
│ ├── Lot Entry
│ │ ├── Add
│ │ ├── Edit
│ │ ├── Delete
│ │ └── View
├── Order Management
├── Add
├── Edit
├── Delete
└── View
Flow Example:
FMDF -> Stock Management -> Tree Stock -> Add
FMDF -> Order Management -> Add
This means:
- FMDF is the root module
- Stock Management is a child module of FMDF
- Tree Stock is a child module of Stock Management
- Add is an action permission under Tree Stock
When a user has the "Tree Stock -> Add" permission, they automatically get access to:
- Tree Stock (parent module)
- Stock Management (grandparent module)
- FMDF (root module)
This hierarchical structure allows for:
- ✅ Flexible permission management
- ✅ Easy sidebar menu visibility control
- ✅ Granular access control at each level
- ✅ Automatic parent permission inheritance
🔗 Links
pkc/role-permission 适用场景与选型建议
pkc/role-permission 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 17 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 12 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「authorization」 「acl」 「laravel」 「roles」 「permissions」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 pkc/role-permission 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 pkc/role-permission 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 pkc/role-permission 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Laravel Multiauth package
Ory-Hydra OAuth 2.0 Client Provider for The PHP League OAuth2-Client
A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.
This package provides a flexible way to add Role-based Permissions to Laravel 6.x
This package provides a flexible way to add Role-based Permissions to Laravel
Laravel JWT auth service package
统计信息
- 总下载量: 17
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 18
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-12