基於 PHP 反射的許可權匯入

黑將軍發表於2018-03-24

之前公司的專案中的管理後臺許可權控制模組,是用PHP反射獲取類方法註釋中的許可權名,但是是用公司內部的框架實現的,沒有在laravel上試過,所以想重新擼一個輪子,廢話不多說,開擼~~ (文采太爛,導致廢話少)

先來看看,最終想要達成的效果

  • 許可權列表
    file
  • 一鍵匯入許可權
    file
  • 控制器註釋
<?php

/**
 * @module 選單管理
 */
class MenuController
{
    /**
     * @permission選單列表
     */
    public function index()
    {
        ...
    }
}

控制器作為一個許可權集合模組,控制器方法為單個許可權,上面的@permission選單列表其實中間有一個空格,編輯儲存的時候總會自動給我加上個連結,不曉得為什麼,難道不小心使用了本論壇的特殊命令 :joy:


接下來是許可權提取

<?php
namespace Tanmo\Admin\Classes;

use Illuminate\Routing\Route;
use Illuminate\Routing\Router;

class Permissions
{
    /**
     * @var \Illuminate\Routing\RouteCollection
     */
    protected $routes;

    /**
     * @var string
     */
    protected $filterNamespace;

    /**
     * @var string
     */
    protected $moduleTag;

    /**
     * @var string
     */
    protected $permissionTag;

    /**
     * Permissions constructor.
     * @param Router $router
     */
    public function __construct(Router $router)
    {
        $this->routes = $router->getRoutes();
        $this->filterNamespace = config('admin.namespace');
        $this->moduleTag = '@module';
        $this->permissionTag = '[@permission](https://learnku.com/users/3492)';
    }

    /**
     * @return array
     */
    public function getAllPermissions()
    {
        $routes = $this->getRoutes();

        $res = [];
        foreach ($routes as &$route) {
            $ref = new \ReflectionClass($route['controller']);
            $classDoc = $ref->getDocComment();
            if ($classDoc != false && $module = $this->getModule($classDoc)) {
                $methodDoc = $ref->getMethod($route['action'])->getDocComment();
                if ($methodDoc != false && ($name = $this->getPermission($methodDoc))) {
                    ///
                    $permission = $route;
                    $permission['module'] = $module;
                    $permission['name'] = $name;

                    ///
                    $res[] = $permission;
                }
            }
        }

        return $res;
    }

    ...
}
  • 通過$filterNamespace來提取需要掃描許可權的名稱空間下的路由,獲取到該路由繫結的控制器名 方法名 uri, 然後用反射類的getDocComment()方法來獲取控制器方法的註釋,提取出module標籤permission標籤
  • 將掃描到的許可權匯入資料庫

第一次寫文章,輕噴~,寫的不到位的,請指出,我改 :joy:
因為沒有找到laravel下,類似這種實現方式的許可權控制包,所以自己擼一個,還不完善,思路也是來自於之前公司的專案,不是我發明的 :satisfied:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

黑將軍(Tanmo)

相關文章