本文目录导读:

在 PHP 中实现“授权注解”(Authorization Annotations)通常需要借助反射和自定义注解解析,因为 PHP 原生不支持注解(直到 PHP 8.0+ 才支持原生注解,但仍需手动处理逻辑)。
下面我给你一个完整可用的示例,演示如何通过注解实现简单的权限控制(@RequireRole)。
定义注解类(PHP 8.0+ 原生注解)
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class RequireRole
{
public array $roles;
public function __construct(string ...$roles)
{
$this->roles = $roles;
}
}
注意:
#[Attribute]标记这是一个注解类,TARGET_METHOD表示可作用于方法。
编写注解解析器(核心逻辑)
class AuthMiddleware
{
public static function check(object $controller, string $method): void
{
$reflection = new ReflectionMethod($controller, $method);
$attributes = $reflection->getAttributes(RequireRole::class);
if (empty($attributes)) {
// 没有权限限制,放行
return;
}
/** @var RequireRole $requireRole */
$requireRole = $attributes[0]->newInstance();
// 模拟获取当前用户角色(实际应从 session / token 获取)
$currentUserRole = $_SESSION['user_role'] ?? 'guest';
if (!in_array($currentUserRole, $requireRole->roles)) {
http_response_code(403);
echo "权限不足,需要角色: " . implode(', ', $requireRole->roles);
exit;
}
}
}
使用注解的业务控制器
class UserController
{
#[RequireRole('admin')]
public function deleteUser(int $userId): void
{
echo "用户 {$userId} 已被删除(管理员权限已验证)";
}
#[RequireRole('admin', 'editor')]
public function editUser(int $userId): void
{
echo "编辑用户 {$userId}(管理员/编辑权限已验证)";
}
public function viewUser(int $userId): void
{
echo "查看用户 {$userId}(无需特殊权限)";
}
}
路由/调用处统一进行权限校验
// 模拟路由分发 $route = $_GET['action'] ?? 'viewUser'; $userId = (int)($_GET['id'] ?? 1); $controller = new UserController(); // 执行权限检查(核心调用) AuthMiddleware::check($controller, $route); // 权限通过后,调用实际方法 $controller->$route($userId);
测试效果
- 当访问
?action=deleteUser&id=5且当前用户角色不是admin→ 显示 403 错误。 - 当访问
?action=editUser&id=3且角色是editor→ 正常执行。 - 当访问
?action=viewUser&id=1→ 直接放行(无注解)。
如果需要兼容 PHP 7.x(没有原生注解)
可以使用 Doctrine Annotations 库,或使用 PHPDoc 注释 手动解析:
/**
* @RequireRole("admin", "editor")
*/
public function editUser(int $userId): void
{
// ...
}
再通过 ReflectionMethod::getDocComment() 和正则提取注解内容。
总结核心流程
- 定义注解类(PHP 8.0+ 用
#[Attribute],旧版用注释标记) - 反射读取注解 → 获取权限要求
- 比较当前用户角色 → 通过则放行,否则拒绝
- 在路由/控制器调用前统一执行
check()
这样你就拥有了一套基于注解的授权系统,适合中小型框架或项目使用,如果需要更成熟的方案,可以看 Symfony Security 或 Laravel Policies + Gates。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播