>php教程 >php手册 >Yii-admin의 권한 제어에 대한 간략한 토론

Yii-admin의 권한 제어에 대한 간략한 토론

WBOY
WBOY원래의
2016-09-01 00:00:48963검색

CMS의 경우 가장 중요한 것은 권한 제어입니다. 특히 일부 복잡한 시나리오, 다중 사용자, 다중 역할, 다중 부서, 자녀-부모 보기 등의 경우에는 더욱 그렇습니다. 최근에는 오프라인 판매 물건을 개발 중인데, 이 시스템은 관리자 측, 지방 측, 고객 측, 매장 측, 판매 측, 부서 측, 부서장 산하 하위 부서 등으로 나누어져 있어 수요가 역겹습니다. 우리 프로젝트는 PHP 세계에서 여전히 인기가 높은 Yii 프레임워크를 사용하여 개발되었습니다. 비록 현재 Laravel이 널리 사용되고 있지만 우리와 같은 일부 부서와 팀에서는 여전히 Yii 프레임워크를 사용하고 있습니다.

저는 Yii 프레임워크를 처음 접했는데 처음에는 이 컴포넌트 중심 프레임워크가 매우 불편했습니다. 그 당시에는 권한을 직접 작성하고 권한 테이블, 연결 테이블 등을 만들려고 계획했지만 yii를 사용하여 문서를 개발하는 방법을 배운 후 yii-admin의 도움으로 권한 제어 RBAC가 있다는 것을 알게 되었습니다. 완벽한 권한과 메뉴 제어가 가능합니다. 본 블로그는 두 부분으로 나누어져 있습니다. 첫 번째 부분에서는 yii-admin 설치, 권한 테이블 생성, 권한 제어 메뉴 사용 및 접근 권한 등 기본 작업을 포함하여 권한 관리 설정 방법을 설명합니다. 대략적인 소개입니다. 자세한 내용은 http://www.manks.top/tag/rbac.html에서 더 자세한 설명을 참조하세요. 단계를 따르는 한 사용하십시오. 두 번째 부분에서는 메뉴 최적화, 하위 페이지 탐색의 선택적 강조 표시, 역할별 메뉴 표시, 권한 감지 개선 등 제가 직접 이해한 내용을 설명하겠습니다.

디렉토리:

1.yii-admin 설립 관련

1. yii-admin 빌드

2. 데이터베이스 권한 테이블 구성

3. 메뉴 관리

2.yii-admin 최적화 및 재작성

1. 메뉴 최적화

2. 네비게이션 하이라이트, 아이콘, 표시 여부

3. 다시 쓰기 권한 감지

1. yii-admin 설립 관련

1. yii-admin 빌드

우선 yii 프레임워크를 설치해야 합니다. yii-admin은 yii 프레임워크를 기반으로 하고 있고 프레임워크가 없으면 어색하기 때문입니다! github에서 직접 소스코드를 다운로드할 수 있습니다

yii2:https://github.com/yiisoft/yii2

 yii2-admin:https://github.com/mdmsoft/yii2-admin

물론 작곡가를 사용하여 설치할 수 있습니다. yii를 설치한 경우 프로젝트 디렉터리로 전환하여 다음 명령을 직접 실행할 수 있습니다.

<span style="color: #008080;">1</span> php composer.phar <span style="color: #0000ff;">require</span> mdmsoft/yii2-admin "~2.0"
<span style="color: #008080;">2</span> php composer.phar update

  然后配置中加入yii-admin的配置项,值的注意的是如果yii2-admin配置在common目录下是全局生效,那么你在执行命令控制台的时候就会报错,所以应将权限控制作用于web模块,我们这个项目没有使用高级模板,所以你可以直接把配置写在config下面的web.php中,配置如下:

先定义别名:

<span style="color: #008080;">1</span> 'aliases' =><span style="color: #000000;"> [
</span><span style="color: #008080;">2</span>     '@mdm/admin' => '@vendor/mdmsoft/yii2-admin',
<span style="color: #008080;">3</span> ],

在modules中添加admin组件:

<span style="color: #008080;">1</span> 'admin' =><span style="color: #000000;"> [
</span><span style="color: #008080;">2</span>     'class' => 'mdm\admin\Module',
<span style="color: #008080;">3</span>     'layout' => '@app/views/layouts/main_nifty',<span style="color: #008000;">//</span><span style="color: #008000;">yii2-admin的导航菜单</span>
<span style="color: #008080;">4</span> ],

添加添加authManager配置项:

需要强调的是,yii中的authManager组件有PhpManager和DbManager两种方式,这两种方式是由区别的,PhpManager将权限关系保存在文件里,DbManager方式,将权限关系保存在数据库。我们采用保存在数据库中的方式。

<span style="color: #008080;">1</span> 'authManager' =><span style="color: #000000;"> [
</span><span style="color: #008080;">2</span>     'class' => 'yii\rbac\DbManager', <span style="color: #008000;">//</span><span style="color: #008000;"> or use 'yii\rbac\DbManager'</span>
<span style="color: #008080;">3</span> ],

添加as access:

<span style="color: #008080;"> 1</span> 'as access' =><span style="color: #000000;"> [
</span><span style="color: #008080;"> 2</span>     'class' => 'mdm\admin\components\AccessControl',
<span style="color: #008080;"> 3</span>     'allowActions' =><span style="color: #000000;"> [
</span><span style="color: #008080;"> 4</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> add or remove allowed actions to this list
</span><span style="color: #008080;"> 5</span> <span style="color: #008000;">        // 'admin/*',
</span><span style="color: #008080;"> 6</span> <span style="color: #008000;">        //'*',</span>
<span style="color: #008080;"> 7</span>         'site/*',
<span style="color: #008080;"> 8</span>         'api/*',
<span style="color: #008080;"> 9</span> <span style="color: #000000;">    ]
</span><span style="color: #008080;">10</span> ],

需要说的是未知不要放错了,如下图所示:

 

2、配置数据库权限表

这一步不用自己去写,命令行切换到yii2目录,执行下面命令,创建rbac需要的表,但是数据库需要自己创建,名字默认是yii2basic,如果要执行命令,就需要把你刚下配置好的配置文件在在console.php中也写一份,如果执行不成功,可以吧生成数据表的脚本拿出来自己执行。

<span style="color: #008080;">1</span> yii migrate --migrationPath=@yii/rbac/<span style="color: #000000;">migrations
</span><span style="color: #008080;">2</span> yii migrate --migrationPath=@mdm/admin/migrations 

如果执行成功会生成5张表,还需要一张user表,你可以自己添加

<span style="color: #008080;">1</span> <span style="color: #000000;">menu             <span style="color: #008000;">//<span style="color: #008000;">菜单表</span></span>
</span><span style="color: #008080;">2</span> auth_rule        <span style="color: #008000;">//</span><span style="color: #008000;">规则表</span>
<span style="color: #008080;">3</span> auth_item_child  <span style="color: #008000;">//</span><span style="color: #008000;">角色对应的权限,parent角色,child权限名</span>
<span style="color: #008080;">4</span> auth_item        <span style="color: #008000;">//</span><span style="color: #008000;">角色、权限表,type=1表示角色,type=2表示权限</span>
<span style="color: #008080;">5</span> auth_assignment  <span style="color: #008000;">//</span><span style="color: #008000;">角色与用户对应关系表</span>

  如果全部成功的话,访问index.php?r=admin 就可以了看到权限的控制可视化页面,如果出错,认真查看错误原因,基本上都是配置不对。配置好的话,访问其他页面就没有权限了,然后你可以修改<span class="hljs-string">as access</span>中的<span class="hljs-string">allowActions</span>,这在开发api或者一些共用模块的时候很有用,因为这些页面不需要进行权限的控制。默认风格的权限控制页面如下图:

3、进行菜单控制

  要进行菜单控制,就需要用到刚才创建的那几个表中的menu表,左侧的导航按照我们的设计应该可以通过权限进行控制,写死的导航不能达到目的,可扩展性不强,所以菜单控制必须要支持。

需要注意的是,如果你的后台框架中用到了自己的layout,你需要自己去指定,我们这个项目就是,有我们自己的layout,上面再添加admin组件的时候已经添加了:

'layout' => '@app/views/layouts/main_nifty',

然后我们操作菜单列表。添加菜单项,然后再打开layout文件,其实获取菜单的逻辑已经写好了,在MenuHelper中,添加命名空间mdm\admin\components\MenuHelper; 然后注销原来的导航,添加下面的代码,基本上就可以实现权限-用户-导航的控制了。

<span style="color: #008080;">1</span> <span style="color: #0000ff;">echo</span> Nav::<span style="color: #000000;">widget(
</span><span style="color: #008080;">2</span> <span style="color: #000000;">    [
</span><span style="color: #008080;">3</span>         "encodeLabels" => <span style="color: #0000ff;">false</span>,
<span style="color: #008080;">4</span>         "options" => ["class" => "sidebar-menu"],
<span style="color: #008080;">5</span>         "items" => MenuHelper::getAssignedMenu(Yii::<span style="color: #800080;">$app</span>->user->id),
<span style="color: #008080;">6</span> <span style="color: #000000;">    ]
</span><span style="color: #008080;">7</span> );

好了说完了,最后看一下这个页面:

二、yii-admin优化和重写

  在使用的过程中,yii-admin实现的导航权限控制远不能满足我们的需求,并且这种组件试的开发,每个操作是完全独立的,比如检查权限,取菜单,取用户信息,每个操作都需要执行SQL来进行。下面是正常的检查权限和得到菜单的sql执行过程,其实这个过程是极其费时的,当用户量比较多,菜单比较大,权限表中的数据非常多的时候是不能这样干的,使用我们自己的sql检测工具可以看到,这个过程执行了20条之多的sql语句:

  在图中可以看出,权限检查涉及了14次的sql查询,菜单涉及了5次sql查询,如此多的sql 执行一旦上线是没有什么并发可言的。yii-admin这个组件提供了方便的权限控制,菜单控制,但是性能上面我们不敢苟同。查看源码你就知道,这个组件在我看来是一个解耦比较高的组件,每个成分之间可以单独的使用,这就需要每个操作必须要有自己独立的数据库来源,说白了就需要每次都执行sql去取到想要的数据,中间很少使用连表查询,其实10条sql做的功能,在连表的情况下,一条sql就搞定了。

  像我这种人是不能忍受这么多不相关的sql执行的,所以我就在根源上面修改了yii-admin的权限检查部分,修改的方法是我自己想的,不一定对,也不一定适合所有的场景,下面就写出来与大家分享。

 

1、菜单的优化

  我们通过查看菜单的生成过程大致会执行了5条以上的sql,这个还算可以,我没有做sql上的优化,原因是我们的菜单是要对应不同的角色和子父级关系,在原来的基础上我添加了一个type来区分是哪种角色能看到这种菜单,以及哪种角色对应某一个菜单显示的层级关系。这样管理员,省代用户,客户都会呈现不同的菜单。即使配置相同的权限,不同层级的用户也会看到不同的菜单。

  我做的优化是缓存菜单的生成数据,我们这个菜单是定制的,没有采用一开始配置的Nav::widget来呈现,而是我们自己循环层级关系,这样虽然麻烦,但是能很好的提取菜单中我们需要的每一个逻辑,比如:面包屑的自动生成就可以每次提取菜单的label,再比如子页面,不同控制器下得左导航的高亮,下面是代码,php和html混写了,以后会慢慢的提取。

<span style="color: #008080;"> 1</span> <ul <span style="color: #0000ff;">class</span>="nav nav-list">
<span style="color: #008080;"> 2</span> <?<span style="color: #000000;">php 
</span><span style="color: #008080;"> 3</span> <span style="color: #800080;">$idx</span> = 1<span style="color: #000000;">;
</span><span style="color: #008080;"> 4</span> <span style="color: #800080;">$request_url</span> = '/' . <span style="color: #800080;">$mod_id</span> . '/' . <span style="color: #800080;">$con_id</span> . '/' . <span style="color: #800080;">$act_id</span> . '/'<span style="color: #000000;">;
</span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$menus_new</span>['list'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$label</span> => <span style="color: #800080;">$menu1</span>): ?>
<span style="color: #008080;"> 6</span> <?<span style="color: #000000;">php
</span><span style="color: #008080;"> 7</span>     <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$menu1</span>['label']) && <span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$menu</span>['url'][0<span style="color: #000000;">])) {
</span><span style="color: #008080;"> 8</span>         <span style="color: #0000ff;">continue</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">10</span> ?>
<span style="color: #008080;">11</span> <?php <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$menu1</span>['items'])):?>
<span style="color: #008080;">12</span>     <li <span style="color: #0000ff;">class</span>="<span style="color: #000000;"><?php 
</span><span style="color: #008080;">13</span>             if (isset(<span style="color: #800080;">$menu1</span>['openurl']) && strstr(<span style="color: #800080;">$menu1</span>['openurl'], <span style="color: #800080;">$request_url</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">14</span> <span style="color: #000000;">                echo 'active';
</span><span style="color: #008080;">15</span>                 <span style="color: #800080;">$breadcrumb</span>[] = <span style="color: #800080;">$menu1</span><span style="color: #000000;">['label'];
</span><span style="color: #008080;">16</span> <span style="color: #000000;">            }
</span><span style="color: #008080;">17</span>         ?>">
<span style="color: #008080;">18</span>         <a href="<?php echo <span style="color: #800080;">$menu1</span>['url'][0] ?>">
<span style="color: #008080;">19</span>             <i <span style="color: #0000ff;">class</span>="menu-icon fa fa-<?php echo <span style="color: #800080;">$menu1</span>['icon'] ?>"></i>
<span style="color: #008080;">20</span>             <span <span style="color: #0000ff;">class</span>="menu-text"> <?php <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$menu1</span>['label'] ?> </span>
<span style="color: #008080;">21</span>         </a>
<span style="color: #008080;">22</span>         <b <span style="color: #0000ff;">class</span>="arrow"></b>
<span style="color: #008080;">23</span>     </li>
<span style="color: #008080;">24</span> <?php <span style="color: #0000ff;">else</span>:?>
<span style="color: #008080;">25</span>     <li <span style="color: #0000ff;">class</span>="<span style="color: #000000;"><?php
</span><span style="color: #008080;">26</span>             if (isset(<span style="color: #800080;">$menu1</span>['openurl']) && strstr(<span style="color: #800080;">$menu1</span>['openurl'], <span style="color: #800080;">$request_url</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">27</span> <span style="color: #000000;">                echo 'open';
</span><span style="color: #008080;">28</span>                 <span style="color: #800080;">$breadcrumb</span>[] = <span style="color: #800080;">$menu1</span><span style="color: #000000;">['label'];
</span><span style="color: #008080;">29</span> <span style="color: #000000;">            }
</span><span style="color: #008080;">30</span>         ?>">
<span style="color: #008080;">31</span>         <a href="index.html"data-target="#multi-cols-<?php echo <span style="color: #800080;">$idx</span> ?>"<span style="color: #0000ff;">class</span>="dropdown-toggle">
<span style="color: #008080;">32</span>             <i <span style="color: #0000ff;">class</span>="menu-icon fa fa-<?php echo <span style="color: #800080;">$menu1</span>['icon'] ?>"></i>
<span style="color: #008080;">33</span>             <span <span style="color: #0000ff;">class</span>="menu-text"> 
<span style="color: #008080;">34</span>                 <?php <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$menu1</span>['label'] ?> 
<span style="color: #008080;">35</span>             </span>
<span style="color: #008080;">36</span>             <b <span style="color: #0000ff;">class</span>="arrow fa fa-angle-down"></b>
<span style="color: #008080;">37</span>         </a>
<span style="color: #008080;">38</span>         <b <span style="color: #0000ff;">class</span>="arrow"></b>
<span style="color: #008080;">39</span>         <ul id="multi-cols-<?php echo <span style="color: #800080;">$idx</span> ?>" <span style="color: #0000ff;">class</span>="submenu">
<span style="color: #008080;">40</span>             <?php <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$menu1</span>['items'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$label</span> => <span style="color: #800080;">$menu2</span>): ?>
<span style="color: #008080;">41</span>             <?<span style="color: #000000;">php 
</span><span style="color: #008080;">42</span>                 <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$menu2</span>) || !<span style="color: #008080;">is_array</span>(<span style="color: #800080;">$menu2</span>)) { <span style="color: #0000ff;">continue</span><span style="color: #000000;">; }
</span><span style="color: #008080;">43</span>                 <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$menu2</span>['items'])):?>
<span style="color: #008080;">44</span>                 <li <span style="color: #0000ff;">class</span>="<span style="color: #000000;"><?php
</span><span style="color: #008080;">45</span>                     if (isset(<span style="color: #800080;">$menu2</span>['openurl']) && strstr(<span style="color: #800080;">$menu2</span>['openurl'], <span style="color: #800080;">$request_url</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">46</span> <span style="color: #000000;">                        echo 'active';
</span><span style="color: #008080;">47</span>                         <span style="color: #800080;">$breadcrumb</span>[] = <span style="color: #800080;">$menu2</span><span style="color: #000000;">['label'];
</span><span style="color: #008080;">48</span> <span style="color: #000000;">                    }
</span><span style="color: #008080;">49</span>                 ?>">
<span style="color: #008080;">50</span>                     <a href="<?php echo <span style="color: #800080;">$menu2</span>['url'][0] ?>">
<span style="color: #008080;">51</span>                         <i <span style="color: #0000ff;">class</span>="menu-icon fa fa-caret-right"></i>
<span style="color: #008080;">52</span>                         <?php <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$menu2</span>['label'] ?>
<span style="color: #008080;">53</span>                     </a>
<span style="color: #008080;">54</span>                     <b <span style="color: #0000ff;">class</span>="arrow"></b>
<span style="color: #008080;">55</span>                 </li>
<span style="color: #008080;">56</span>             <?php <span style="color: #0000ff;">else</span>:?>
<span style="color: #008080;">57</span>                 <li <span style="color: #0000ff;">class</span>="<span style="color: #000000;"><?php 
</span><span style="color: #008080;">58</span>                     if (isset(<span style="color: #800080;">$menu2</span>['openurl']) && strstr(<span style="color: #800080;">$menu2</span>['openurl'], <span style="color: #800080;">$request_url</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">59</span> <span style="color: #000000;">                        echo 'open';
</span><span style="color: #008080;">60</span>                         <span style="color: #800080;">$breadcrumb</span>[] = <span style="color: #800080;">$menu2</span><span style="color: #000000;">['label'];
</span><span style="color: #008080;">61</span> <span style="color: #000000;">                    }
</span><span style="color: #008080;">62</span>                     ?>">
<span style="color: #008080;">63</span>                     <a href="#" <span style="color: #0000ff;">class</span>="dropdown-toggle">
<span style="color: #008080;">64</span>                         <i <span style="color: #0000ff;">class</span>="menu-icon fa fa-caret-right"></i>
<span style="color: #008080;">65</span>                         <?php <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$menu2</span>['label'] ?>
<span style="color: #008080;">66</span>                         <b <span style="color: #0000ff;">class</span>="arrow fa fa-angle-down"></b>
<span style="color: #008080;">67</span>                     </a>
<span style="color: #008080;">68</span>                     <b <span style="color: #0000ff;">class</span>="arrow"></b>
<span style="color: #008080;">69</span>                     <ul <span style="color: #0000ff;">class</span>="submenu">
<span style="color: #008080;">70</span>                         <?php <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$menu2</span>['items'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$label</span> => <span style="color: #800080;">$url</span>): ?>
<span style="color: #008080;">71</span>                         <?php <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$url</span>) || !<span style="color: #008080;">is_array</span>(<span style="color: #800080;">$url</span>)) { <span style="color: #0000ff;">continue</span>; } ?>
<span style="color: #008080;">72</span>                         <li <span style="color: #0000ff;">class</span>="<span style="color: #000000;"><?php
</span><span style="color: #008080;">73</span>                             if (isset(<span style="color: #800080;">$url</span>['openurl']) && strstr(<span style="color: #800080;">$url</span>['openurl'], <span style="color: #800080;">$request_url</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">74</span> <span style="color: #000000;">                                echo 'active';
</span><span style="color: #008080;">75</span>                                 <span style="color: #800080;">$breadcrumb</span>[] = <span style="color: #800080;">$url</span><span style="color: #000000;">['label'];
</span><span style="color: #008080;">76</span> <span style="color: #000000;">                            }
</span><span style="color: #008080;">77</span>                             ?>">
<span style="color: #008080;">78</span>                             <a href="<?php echo <span style="color: #800080;">$url</span>['url'][0] ?>">
<span style="color: #008080;">79</span>                               <i <span style="color: #0000ff;">class</span>="menu-icon fa fa-caret-right"></i>
<span style="color: #008080;">80</span>                               <?php <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$url</span>['label'] ?>
<span style="color: #008080;">81</span>                             </a>
<span style="color: #008080;">82</span>                             <b <span style="color: #0000ff;">class</span>="arrow"></b>
<span style="color: #008080;">83</span>                         </li>
<span style="color: #008080;">84</span>                         <?php <span style="color: #0000ff;">endforeach</span> ?>
<span style="color: #008080;">85</span>                     </ul>
<span style="color: #008080;">86</span>                </li>
<span style="color: #008080;">87</span>             <?php <span style="color: #0000ff;">endif</span>?>
<span style="color: #008080;">88</span>             <?php <span style="color: #0000ff;">endforeach</span> ?>
<span style="color: #008080;">89</span>         </ul>
<span style="color: #008080;">90</span>     </li>
<span style="color: #008080;">91</span> <?php <span style="color: #0000ff;">endif</span>?>
<span style="color: #008080;">92</span> <?php <span style="color: #800080;">$idx</span>++; ?>
<span style="color: #008080;">93</span> <?php <span style="color: #0000ff;">endforeach</span> ?>
<span style="color: #008080;">94</span> </ul>

 

  这个导航是我自己改了好多版总结出适合我们自己的方案,其中$breadcrumb是控制面包屑的显示,有时间我会抽离php。我介绍的是菜单优化,现在才完成了第一步菜单的显示,说到优化我是采用缓存菜单数据的策略,就是缓存上面那个$menus_new['list'],策略如下:

  这个策略使用角色缓存数据,就是使用每个角色的权限加上uid和环境配置取MD5后生成key,考虑到用户比较多每个用户都缓存的话开销太大,并且用户相同权限的的比较多,特殊权限的可以特殊对待,这样省去了存储好多重复的数据,环境配置是区分线上数据和测试数据,便于我们进行调试。

  过期机制:重要的是缓存的过期机制,缓存有了但是当菜单或者权限发生变化的时候就要更新缓存,这里我们引入了版本的概念,能做到缓存变更的最小开销。比如菜单变化,所有人导航都应该修改,这里我们在redis中加入一个导航版本的变量,每次读入缓存的时候都会先判断这个版本与缓存中自己存储版本是否一致,如果一致证明导航没有变化,如果不一致认为菜单有修改,导航已过期,需要重新得到缓存,这样相同的角色,只要有一个人更新了导航,其他人下次再进来的时候就会访问到最新的导航(统一角色)。这个全局的redis变量会在导航变更和权限变更的时候自动加1,保证版本的变化,这样如果有4类角色,几万人的用户,实际的数据修改只发生的4次(实际会比这个多,比如同一个角色不同的权限,那么他对应的redis key 就不一样,它需要自己去取缓存)。具体的代码实现如下:

<span style="color: #008080;"> 1</span> <span style="color: #800080;">$user_id</span> = Yii::<span style="color: #800080;">$app</span>->user-><span style="color: #000000;">id;
</span><span style="color: #008080;"> 2</span> <span style="color: #800080;">$breadcrumb</span> =<span style="color: #000000;"> [];
</span><span style="color: #008080;"> 3</span> <span style="color: #800080;">$menus_new</span>['list'] = MenuHelper::getAssignedMenu(<span style="color: #800080;">$user_id</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 4</span> 
<span style="color: #008080;"> 5</span> <span style="color: #800080;">$redis_key</span> = MenuHelper::getMenuKeyByUserId(<span style="color: #800080;">$user_id</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 6</span> <span style="color: #800080;">$redis_menu</span> = Yii::<span style="color: #800080;">$app</span>->redis->get(<span style="color: #800080;">$redis_key</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 7</span> <span style="color: #800080;">$redis_varsion</span> =<span style="color: #000000;"> getVersion();
</span><span style="color: #008080;"> 8</span> 
<span style="color: #008080;"> 9</span> <span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$redis_menu</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">10</span>     <span style="color: #800080;">$menus_new</span> = json_decode(<span style="color: #800080;">$redis_menu</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">);
</span><span style="color: #008080;">11</span>     <span style="color: #800080;">$old_version</span> = <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$menus_new</span>['version']) ? <span style="color: #800080;">$menus_new</span>['version'] : ''<span style="color: #000000;">;
</span><span style="color: #008080;">12</span> 
<span style="color: #008080;">13</span>     <span style="color: #008000;">//</span><span style="color: #008000;">判断菜单的版本号,便于及时更新缓存</span>
<span style="color: #008080;">14</span>     <span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$menus_new</span>['list']) || <span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$old_version</span>) || <span style="color: #008080;">intval</span>(<span style="color: #800080;">$old_version</span>) != <span style="color: #800080;">$redis_varsion</span><span style="color: #000000;">) {
</span><span style="color: #008080;">15</span>         <span style="color: #800080;">$menus_new</span> = getMenu(<span style="color: #800080;">$user_id</span>, <span style="color: #800080;">$redis_varsion</span>, <span style="color: #800080;">$redis_key</span><span style="color: #000000;">);
</span><span style="color: #008080;">16</span>         <span style="color: #800080;">$log</span> =<span style="color: #000000;"> json_encode([
</span><span style="color: #008080;">17</span>             'user_id' => <span style="color: #800080;">$user_id</span>,
<span style="color: #008080;">18</span>             'varsion' => <span style="color: #800080;">$redis_varsion</span>,
<span style="color: #008080;">19</span>             'redis_key' => <span style="color: #800080;">$redis_key</span>,
<span style="color: #008080;">20</span>             'value' => <span style="color: #800080;">$menus_new</span>
<span style="color: #008080;">21</span> <span style="color: #000000;">        ]);
</span><span style="color: #008080;">22</span>         writeLog(<span style="color: #800080;">$log</span>, 'update_menu'<span style="color: #000000;">);
</span><span style="color: #008080;">23</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">24</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {
</span><span style="color: #008080;">25</span>     <span style="color: #800080;">$menus_new</span> = getMenu(<span style="color: #800080;">$user_id</span>, <span style="color: #800080;">$redis_varsion</span>, <span style="color: #800080;">$redis_key</span><span style="color: #000000;">);
</span><span style="color: #008080;">26</span> <span style="color: #000000;">}
</span><span style="color: #008080;">27</span> 
<span style="color: #008080;">28</span> <span style="color: #0000ff;">function</span> getMenu(<span style="color: #800080;">$user_id</span>, <span style="color: #800080;">$varsion</span>, <span style="color: #800080;">$redis_key</span><span style="color: #000000;">)
</span><span style="color: #008080;">29</span> <span style="color: #000000;">{
</span><span style="color: #008080;">30</span>     <span style="color: #800080;">$menus_new</span>['list'] = MenuHelper::getAssignedMenu(<span style="color: #800080;">$user_id</span><span style="color: #000000;">);
</span><span style="color: #008080;">31</span>     <span style="color: #800080;">$menus_new</span>['version'] = <span style="color: #800080;">$varsion</span><span style="color: #000000;">;
</span><span style="color: #008080;">32</span>     Yii::<span style="color: #800080;">$app</span>->redis->set(<span style="color: #800080;">$redis_key</span>, json_encode(<span style="color: #800080;">$menus_new</span><span style="color: #000000;">));
</span><span style="color: #008080;">33</span>     Yii::<span style="color: #800080;">$app</span>->redis->expire(<span style="color: #800080;">$redis_key</span>, 300<span style="color: #000000;">);
</span><span style="color: #008080;">34</span>     <span style="color: #0000ff;">return</span> <span style="color: #800080;">$menus_new</span><span style="color: #000000;">;
</span><span style="color: #008080;">35</span> <span style="color: #000000;">}
</span><span style="color: #008080;">36</span> 
<span style="color: #008080;">37</span> <span style="color: #008000;">//</span><span style="color: #008000;">设置更新key便于时时更新redis</span>
<span style="color: #008080;">38</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getVersion()
</span><span style="color: #008080;">39</span> <span style="color: #000000;">{
</span><span style="color: #008080;">40</span>     <span style="color: #800080;">$version_key</span> = Yii::<span style="color: #800080;">$app</span>->params['redis_key']['menu_prefix'] . <span style="color: #008080;">md5</span>(Yii::<span style="color: #800080;">$app</span>->params['redis_key']['menu_version'] . Yii::<span style="color: #800080;">$app</span>->db-><span style="color: #000000;">dsn);
</span><span style="color: #008080;">41</span>     <span style="color: #800080;">$version_val</span> = Yii::<span style="color: #800080;">$app</span>->redis->get(<span style="color: #800080;">$version_key</span><span style="color: #000000;">);
</span><span style="color: #008080;">42</span> 
<span style="color: #008080;">43</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$version_val</span>) ? 1 : <span style="color: #800080;">$version_val</span><span style="color: #000000;">;
</span><span style="color: #008080;">44</span> }

生成key和更新key的逻辑如下:

<span style="color: #008080;"> 1</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*
</span><span style="color: #008080;"> 2</span> <span style="color: #008000;"> * get menu one user by the id
</span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @param  $user_id
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @return key string
</span><span style="color: #008080;"> 5</span>  <span style="color: #008000;">*/</span>
<span style="color: #008080;"> 6</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> getMenuKeyByUserId(<span style="color: #800080;">$user_id</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 7</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 8</span>     <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$user_id</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 9</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
</span><span style="color: #008080;">10</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">11</span> 
<span style="color: #008080;">12</span>     <span style="color: #800080;">$list</span> = (<span style="color: #0000ff;">new</span> \yii\db\Query())->select('**'<span style="color: #000000;">)
</span><span style="color: #008080;">13</span>                                  ->from('**'<span style="color: #000000;">)
</span><span style="color: #008080;">14</span>                                  ->where(['user_id' => <span style="color: #800080;">$user_id</span><span style="color: #000000;">])
</span><span style="color: #008080;">15</span>                                  -><span style="color: #000000;">all();
</span><span style="color: #008080;">16</span> 
<span style="color: #008080;">17</span>     <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$list</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">18</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
</span><span style="color: #008080;">19</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">20</span> 
<span style="color: #008080;">21</span>     <span style="color: #800080;">$role_str</span> = ''<span style="color: #000000;">;
</span><span style="color: #008080;">22</span>     <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$list</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$key</span> => <span style="color: #800080;">$value</span><span style="color: #000000;">) {
</span><span style="color: #008080;">23</span>         <span style="color: #800080;">$role_str</span> .= <span style="color: #800080;">$value</span>['item_name'<span style="color: #000000;">];
</span><span style="color: #008080;">24</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">25</span> 
<span style="color: #008080;">26</span>     <span style="color: #800080;">$redis_key</span> = Yii::<span style="color: #800080;">$app</span>->params['key'] . <span style="color: #008080;">md5</span>(<span style="color: #800080;">$role_str</span> . Yii::<span style="color: #800080;">$app</span>->db-><span style="color: #000000;">dsn);
</span><span style="color: #008080;">27</span> 
<span style="color: #008080;">28</span>     <span style="color: #0000ff;">return</span> <span style="color: #800080;">$redis_key</span><span style="color: #000000;">;
</span><span style="color: #008080;">29</span> <span style="color: #000000;">}
</span><span style="color: #008080;">30</span> 
<span style="color: #008080;">31</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*
</span><span style="color: #008080;">32</span> <span style="color: #008000;"> * 修改菜单更新状态,更新redis
</span><span style="color: #008080;">33</span>  <span style="color: #008000;">*/</span>
<span style="color: #008080;">34</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> UpdateMenuVersion()
</span><span style="color: #008080;">35</span> <span style="color: #000000;">{
</span><span style="color: #008080;">36</span>     <span style="color: #800080;">$version_key</span> = Yii::<span style="color: #800080;">$app</span>->params['key'] . <span style="color: #008080;">md5</span>(Yii::<span style="color: #800080;">$app</span>->params['key'] . Yii::<span style="color: #800080;">$app</span>->db-><span style="color: #000000;">dsn);
</span><span style="color: #008080;">37</span>     <span style="color: #800080;">$version_val</span> = Yii::<span style="color: #800080;">$app</span>->redis->get(<span style="color: #800080;">$version_key</span><span style="color: #000000;">);
</span><span style="color: #008080;">38</span> 
<span style="color: #008080;">39</span>     <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$version_val</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">40</span>         <span style="color: #800080;">$version_val</span> = '1'<span style="color: #000000;">;
</span><span style="color: #008080;">41</span>     } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {
</span><span style="color: #008080;">42</span>         <span style="color: #800080;">$version_val</span>++<span style="color: #000000;">;
</span><span style="color: #008080;">43</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">44</span> 
<span style="color: #008080;">45</span>     <span style="color: #800080;">$log</span> =<span style="color: #000000;"> json_encode([
</span><span style="color: #008080;">46</span>         'user_id' => Yii::<span style="color: #800080;">$app</span>->user->id, 
<span style="color: #008080;">47</span>         'version_key' => <span style="color: #800080;">$version_key</span>, 
<span style="color: #008080;">48</span>         'version_val' => <span style="color: #800080;">$version_val</span>
<span style="color: #008080;">49</span> <span style="color: #000000;">    ]);
</span><span style="color: #008080;">50</span>     writeLog(<span style="color: #800080;">$log</span>, 'update_menu_version'<span style="color: #000000;">);
</span><span style="color: #008080;">51</span> 
<span style="color: #008080;">52</span>     Yii::<span style="color: #800080;">$app</span>->redis->set(<span style="color: #800080;">$version_key</span>, <span style="color: #800080;">$version_val</span><span style="color: #000000;">);
</span><span style="color: #008080;">53</span> }

 

2、导航的高亮,图标,是否显示

  默认的导航高亮是按照模块,控制器,方法来进行直接匹配的,这样一来有一种需求无法满足,比如:A控制器下得页面下载B控制器下面高亮,这种事无法实现的,所以要修改他们高亮机制。我们没有再采用他的高亮逻辑,而是自己实现了一个新的逻辑。我首先把要高亮的页面url加入到菜单的data里面,data是一个json数据,如下所示:

{"icon": "fa fa-home", "visible": <span style="color: #0000ff;">true</span>, "openurl":"/web/site/index/"}

  这样我们通过openurl就能知道哪个导航高亮,在页面中直接判断当前请求的url在不在这个openurl里面就可以,但是这样做有缺点,必须要有把高亮的页面加入到要高亮的导航里面,如果页面太多这种方式不怎么好,但是我没有想到更好的方法去解决,如果哪位大神有好的方法可以在评论中写出,非常感谢。

  图标和可见性的控制可以借助于MenuHelper中getAssignedMenu的回调方法实现,你可以在调用该方法的时候传入回调方法,我直接写的匿名方法,添加在了该方法里面,如下所示:

<span style="color: #008080;"> 1</span> <span style="color: #800080;">$user_type</span> = Yii::<span style="color: #800080;">$app</span>->user->identity-><span style="color: #000000;">type;
</span><span style="color: #008080;"> 2</span> <span style="color: #800080;">$customer_id</span> = Yii::<span style="color: #800080;">$app</span>->user->identity-><span style="color: #000000;">customer_id;
</span><span style="color: #008080;"> 3</span> 
<span style="color: #008080;"> 4</span> <span style="color: #800080;">$callback_func</span> = <span style="color: #0000ff;">function</span>(<span style="color: #800080;">$menu</span>) <span style="color: #0000ff;">use</span> (<span style="color: #800080;">$user_type</span>, <span style="color: #800080;">$customer_id</span><span style="color: #000000;">) {
</span><span style="color: #008080;"> 5</span>     <span style="color: #800080;">$data</span> = json_decode(<span style="color: #800080;">$menu</span>['data'], <span style="color: #0000ff;">true</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 6</span>     <span style="color: #800080;">$items</span> = <span style="color: #800080;">$menu</span>['children'<span style="color: #000000;">];
</span><span style="color: #008080;"> 7</span> 
<span style="color: #008080;"> 8</span>     <span style="color: #800080;">$return</span> =<span style="color: #000000;"> [
</span><span style="color: #008080;"> 9</span>         'label' => <span style="color: #800080;">$menu</span>['name'],
<span style="color: #008080;">10</span>         'url' => [<span style="color: #800080;">$menu</span>['route']],
<span style="color: #008080;">11</span> <span style="color: #000000;">    ];
</span><span style="color: #008080;">12</span> 
<span style="color: #008080;">13</span>     <span style="color: #800080;">$return</span>['visible'] = <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$data</span>['visible']) ? <span style="color: #800080;">$data</span>['visible'] : ''<span style="color: #000000;">;
</span><span style="color: #008080;">14</span> 
<span style="color: #008080;">15</span>     <span style="color: #008000;">//</span><span style="color: #008000;">菜单隐藏的逻辑</span>
<span style="color: #008080;">16</span>     <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$return</span>['visible'<span style="color: #000000;">])) {
</span><span style="color: #008080;">17</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
</span><span style="color: #008080;">18</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">19</span> 
<span style="color: #008080;">20</span>     <span style="color: #800080;">$return</span>['icon'] = <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$data</span>['icon']) ? <span style="color: #800080;">$data</span>['icon'] : ''<span style="color: #000000;">;
</span><span style="color: #008080;">21</span> 
<span style="color: #008080;">22</span>     <span style="color: #008000;">//</span><span style="color: #008000;">控制菜单打开的逻辑</span>
<span style="color: #008080;">23</span>     <span style="color: #800080;">$return</span>['openurl'] = <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$data</span>['openurl']) ? <span style="color: #800080;">$data</span>['openurl'] : ''<span style="color: #000000;">;
</span><span style="color: #008080;">24</span> 
<span style="color: #008080;">25</span>     <span style="color: #800080;">$items</span> && <span style="color: #800080;">$return</span>['items'] = <span style="color: #800080;">$items</span><span style="color: #000000;">;
</span><span style="color: #008080;">26</span>     <span style="color: #0000ff;">return</span> <span style="color: #800080;">$return</span><span style="color: #000000;">;
</span><span style="color: #008080;">27</span> };

 

3、重写权限检测

  刚才已经说了,yii-admin 的权限检测执行太费时间,执行SQL太多,所以我打算重写他的权限检查的方法,通过读源码可以看到,他们检查是通过user中的can方法调用的,然后通过mdm\admin\components\AccessControl中的beforeAction实现的,我们可以看一下:

<span style="color: #008080;"> 1</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*
</span><span style="color: #008080;"> 2</span> <span style="color: #008000;"> * @inheritdoc
</span><span style="color: #008080;"> 3</span>  <span style="color: #008000;">*/</span>
<span style="color: #008080;"> 4</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> beforeAction(<span style="color: #800080;">$action</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 5</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 6</span>     <span style="color: #800080;">$actionId</span> = <span style="color: #800080;">$action</span>-><span style="color: #000000;">getUniqueId();
</span><span style="color: #008080;"> 7</span>     <span style="color: #800080;">$user</span> = <span style="color: #800080;">$this</span>-><span style="color: #000000;">getUser();
</span><span style="color: #008080;"> 8</span> 
<span style="color: #008080;"> 9</span>     <span style="color: #008000;">//</span><span style="color: #008000;">预留系统检查权限的逻辑,一旦重写检查权限失败,调用系统检查权限的方法</span>
<span style="color: #008080;">10</span>     <span style="color: #0000ff;">if</span> (<span style="color: #800080;">$user</span>->can('/' . <span style="color: #800080;">$actionId</span><span style="color: #000000;">)) {
</span><span style="color: #008080;">11</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
</span><span style="color: #008080;">12</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">13</span>     <span style="color: #800080;">$obj</span> = <span style="color: #800080;">$action</span>-><span style="color: #000000;">controller;
</span><span style="color: #008080;">14</span>     <span style="color: #0000ff;">do</span><span style="color: #000000;"> {
</span><span style="color: #008080;">15</span>         <span style="color: #0000ff;">if</span> (<span style="color: #800080;">$user</span>->can('/' . <span style="color: #008080;">ltrim</span>(<span style="color: #800080;">$obj</span>->getUniqueId() . '/*', '/'<span style="color: #000000;">))) {
</span><span style="color: #008080;">16</span>             <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
</span><span style="color: #008080;">17</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">18</span>         <span style="color: #800080;">$obj</span> = <span style="color: #800080;">$obj</span>-><span style="color: #000000;">module;
</span><span style="color: #008080;">19</span>     } <span style="color: #0000ff;">while</span> (<span style="color: #800080;">$obj</span> !== <span style="color: #0000ff;">null</span><span style="color: #000000;">);
</span><span style="color: #008080;">20</span> 
<span style="color: #008080;">21</span>     <span style="color: #800080;">$this</span>->denyAccess(<span style="color: #800080;">$user</span><span style="color: #000000;">);
</span><span style="color: #008080;">22</span> }

전체 권한 확인에는 하위-상위 확인이 포함되므로, 즉 /admin/menu/update의 권한은 /admin/menu/* 및 /admin/* 및 /*에 표시되므로 살펴보겠습니다. $user->can에 대한 호출은 do -while을 사용하여 수행되며, 이는 검사의 복잡성을 증가시키고 실행되는 SQL은 일괄적으로 증가합니다. 모든 상위 검사는 완전히 새로운 것입니다. 그래서 가장 역겨운 점은 관심 있는 학생들이 그의 프로세스를 살펴볼 수 있다는 것입니다. 이를 탐지하기 위해 이 함수를 호출하면 실행된 SQL이 평소만큼 많지 않다는 것을 알 수 있습니다.

다음은 로그인하지 않은 사용자에 대한 권한, 역할, 일괄 확인 및 권한 확인과 호환되는 SQL 재작성 방법입니다.

<span style="color: #008080;"> 1</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*
</span><span style="color: #008080;"> 2</span> <span style="color: #008000;"> * 권한 판단 방법(아직 이 방법을 사용하지 마십시오. 사용된 시스템 방법은 매우 비효율적이므로 다시 작성할 시간이 있을 때까지 기다리십시오)
</span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @param string/array $permission_name 권한 값(URL 또는 권한 이름)/일괄 감지를 배열에 전달할 수 있습니다.
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @param int $user 사용자 ID, 값이 전달되지 않으면 현재 로그인된 사용자가 사용됩니다.
</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @return bolen
</span><span style="color: #008080;"> 6</span> <span style="color: #008000;"> * @author zhaoyafei
</span><span style="color: #008080;"> 7</span> <span style="color: #008000;">*/</span>
<span style="color: #008080;"> 8</span> <span style="color: #0000ff;">공개</span> <span style="color: #0000ff;">정적</span> <span style="color: #0000ff;">함수</span>PermissionCheck(<span style="color: #800080;">$permission_name</span>, <span style="color: #800080;">$user</span> = 0<span style="color: #000000;">)
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 10</span> <span style="color: #008000;">//</span><span style="color: #008000;">로그인 여부 확인</span>
<span style="color: #008080;"> 11</span> <span style="color: #0000ff;">if</span> (Yii::<span style="color: #800080;">$app</span>->user-><span style="color: #000000;">isGuest) {
</span><span style="color: #008080;"> 12</span> Yii::<span style="color: #800080;">$app</span>->response->redirect('/site/login'<span style="color: #000000;">);
</span><span style="color: #008080;"> 13</span> <span style="color: #000000;"> }
</span><span style="color: #008080;"> 14</span>
<span style="color: #008080;"> 15</span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">비어 있음</span>(<span style="color: #800080;">$permission_name</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 16</span> <span style="color: #0000ff;">반품</span> <span style="color: #0000ff;">거짓</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 17</span> <span style="color: #000000;"> }
</span><span style="color: #008080;"> 18</span>
<span style="color: #008080;"> 19</span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">비어 있음</span>(<span style="color: #800080;">$user</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 20</span> <span style="color: #800080;">$user</span> = Yii::<span style="color: #800080;">$app</span>->user-><span style="color: #000000;">id;
</span><span style="color: #008080;"> 21</span> <span style="color: #000000;"> }
</span><span style="color: #008080;"> 22</span>
<span style="color: #008080;"> 23</span> <span style="color: #008000;">//</span><span style="color: #008000;">관리자 권한은 true를 직접 반환할 수 없습니다. 관리자 유형 = 1은 비관리자 권한이 있는 사람을 가리킵니다(함정이 있음).
</span><span style="color: #008080;"> 24</span>
<span style="color: #008080;"> 25</span> <span style="color: #008000;"> //익명 메소드, 관리자가 값을 반환할 때 상황을 처리 </span>
<span style="color: #008080;"> 26</span> <span style="color: #008000;">/*</span><span style="color: #008000;">$setAdminSet = function($param) use ($permission_name) {
</span><span style="color: #008080;"> 27</span> <span style="color: #008000;"> $paramtmp = $permission_name;
</span><span style="color: #008080;"> 28</span> <span style="color: #008000;"> if (is_array($paramtmp)) {
</span><span style="color: #008080;"> 29</span> <span style="color: #008000;"> if (count($paramtmp) == 1) {
</span><span style="color: #008080;"> 30</span> <span style="color: #008000;"> true를 반환합니다.
</span><span style="color: #008080;"> 31</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 32</span>
<span style="color: #008080;"> 33</span> <span style="color: #008000;"> $paramtmp = array_flip($paramtmp);
</span><span style="color: #008080;"> 34</span> <span style="color: #008000;"> foreach ($paramtmp as $key => &$value) {
</span><span style="color: #008080;"> 35</span> <span style="color: #008000;"> $value = true;
</span><span style="color: #008080;"> 36</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 37</span> <span style="color: #008000;"> }또 다른 {
</span><span style="color: #008080;"> 38</span> <span style="color: #008000;"> $paramtmp = true;
</span><span style="color: #008080;"> 39</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 40</span> <span style="color: #008000;"> return $paramtmp;
</span><span style="color: #008080;"> 41</span> <span style="color: #008000;"> };</span><span style="color: #008000;">*/</span>
<span style="color: #008080;"> 42</span> 
<span style="color: #008080;"> 43</span> <span style="color: #008000;">//</span><span style="color: #008000;">检查是否是管理员, 管理员퉁有权限</span>
<span style="color: #008080;"> 44</span> <span style="color: #008000;">/*</span><span style="color: #008000;">if (비어 있음($user)) {
</span><span style="color: #008080;"> 45</span> <span style="color: #008000;"> $user = Yii::$app->user->id;
</span><span style="color: #008080;"> 46</span> <span style="color: #008000;"> $user_type = Yii::$app->user->identity->type;
</span><span style="color: #008080;"> 47</span> 
<span style="color: #008080;"> 48</span> <span style="color: #008000;"> if ($user_type == TYPE_ADMIN) {
</span><span style="color: #008080;"> 49</span> <span style="color: #008000;"> return $setAdminSet($permission_name);
</span><span style="color: #008080;"> 50</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 51</span> 
<span style="color: #008080;"> 52</span> <span style="color: #008000;"> } else {
</span><span style="color: #008080;"> 53</span> <span style="color: #008000;"> $user_sql = "xm_user WHERE id = :id에서 유형 선택";
</span><span style="color: #008080;"> 54</span> <span style="color: #008000;"> $user_info = Yii::$app->db->createCommand($user_sql)->bindValue(":id", $user)->queryOne ();
</span><span style="color: #008080;"> 55</span> <span style="color: #008000;"> if (empty($user_info)) {
</span><span style="color: #008080;"> 56</span> <span style="color: #008000;"> false를 반환합니다.
</span><span style="color: #008080;"> 57</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 58</span> 
<span style="color: #008080;"> 59</span> <span style="color: #008000;"> if ($user_info['type'] == TYPE_ADMIN) {
</span><span style="color: #008080;"> 60</span> <span style="color: #008000;"> return $setAdminSet($permission_name);
</span><span style="color: #008080;"> 61</span> <span style="color: #008000;"> }
</span><span style="color: #008080;"> 62</span> <span style="color: #008000;"> }</span><span style="color: #008000;">*/</span>
<span style="color: #008080;">63</span> 
<span style="color: #008080;"> 64</span> <span style="color: #008000;">//</span><span style="color: #008000;">根据用户去取权限</span>
<span style="color: #008080;"> 65</span> <span style="color: #800080;">$permission_list</span> =<span style="color: #000000;"> [];
</span><span style="color: #008080;"> 66</span> <span style="color: #800080;">$sql</span> = "<span style="color: #000000;">xc.child, xc1.child를 xm_auth_할당 xa의 role_name으로 선택 
</span><span style="color: #008080;"> 67</span> <span style="color: #000000;"> 내부 조인 xm_auth_item_child xc ON xa.item_name = xc.parent
</span><span style="color: #008080;"> 68</span> <span style="color: #000000;"> 왼쪽 조인 xm_auth_item_child xc1 ON xc.child = xc1.parent
</span><span style="color: #008080;"> 69</span> xa.user_id = :user_id"<span style="color: #000000;">;
</span><span style="color: #008080;"> 70</span> <span style="color: #800080;">$permission</span> = Yii::<span style="color: #800080;">$app</span>->db->createCommand(<span style="color: #800080;">$sql</span><span style="color: #000000;"> )
</span><span style="color: #008080;"> 71</span> ->bindValue(":user_id", <span style="color: #800080;">$user</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 72</span> -><span style="color: #000000;">queryAll();
</span><span style="color: #008080;"> 73</span> 
<span style="color: #008080;"> 74</span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">비어 있음</span>(<span style="color: #800080;">$permission</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 75</span> <span style="color: #0000ff;">반품</span> <span style="color: #0000ff;">거짓</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 76</span> <span style="color: #000000;"> }</span><span style="color: #008080;"> 77</span>
<span style="color: #008080;"> 78</span> <span style="color: #008000;">//</span><span style="color: #008000;">통합 권한 목록</span>
<span style="color: #008080;"> 79</span> <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$permission</span> <span style="color: #0000f"></span>
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.