Home > php教程 > php手册 > body text

A brief discussion on permission control of Yii-admin

WBOY
Release: 2016-09-01 00:00:48
Original
916 people have browsed it

When it comes to CMS, the most important thing is permission control, especially in some complex scenarios, multiple users, multiple roles, multiple departments, child-parent viewing, etc. Recently, I am developing an offline sales stuff. This system is divided into administrator end, provincial end, client end, store end, sales end, department end, sub-departments under the department boss, etc., disgusting demand. Our project is developed using the Yii framework, which is still quite popular in the PHP world. Although Laravel is now rampant, some departments and teams still use the Yii framework, such as us.

I am new to the Yii framework, and at first I was very uncomfortable with this component-oriented framework. At that time, I planned to write permissions by myself, create permission tables, association tables, etc., but after learning to use yii to develop documents, I discovered that there is a permission control RBAC. With the help of yii-admin, perfect permissions and menu control can be achieved. This blog is divided into two parts. In the first part, I will describe how to set up permission management, including basic operations such as installing yii-admin, creating permission tables, using permission control menus and access permissions. This part will give a rough introduction. I would like to see more details. You can refer to this more detailed explanation for the steps: http://www.manks.top/tag/rbac.html. After all, it is not difficult to set up and use, as long as you follow the steps. In the second part, I will explain my own understanding, including: optimization of menus, selective highlighting of sub-page navigation, displaying menus by roles, improvements in permission detection, etc.

Directory:

1. Related to the establishment of yii-admin

1. Build yii-admin

2. Configure database permission table

3. Carry out menu control

2. yii-admin optimization and rewriting

1. Optimization of menu

2. Navigation highlight, icon, whether to display

3. Rewrite permission detection

1. Related to the establishment of yii-admin

1. Build yii-admin

First you should install a yii framework, because yii-admin is based on the yii framework, and it’s useless without a framework! You can download the source code directly from github

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

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

 Of course you can use composer to install it, which is best. If you have installed yii, you can switch to the project directory and directly execute the following command:

<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
Copy after login

  然后配置中加入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> ],
Copy after login

在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> ],
Copy after login

添加添加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> ],
Copy after login

添加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> ],
Copy after login

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

 

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 
Copy after login

如果执行成功会生成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>
Copy after login

  如果全部成功的话,访问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',
Copy after login

然后我们操作菜单列表。添加菜单项,然后再打开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> );
Copy after login

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

二、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>
Copy after login

 

  这个导航是我自己改了好多版总结出适合我们自己的方案,其中$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> }
Copy after login

生成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> }
Copy after login

 

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

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

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

  这样我们通过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> };
Copy after login

 

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> }
Copy after login

 Because the full permissions check includes child-parent checks, that is to say, the permissions of /admin/menu/update are visible to /admin/menu/* and /admin/* and /*, so we will see $ User->can will be called using do -while, which will increase the complexity of the check, and the executed SQL will increase in batches. Think about it, every parent check is a brand new function call. , so the most disgusting thing is this. Interested students can take a look at his process. When you call this function to detect it yourself, you will find that the executed SQL is not as much as usual.

The following is my rewriting method, a SQL that is compatible with permissions, roles, batch checks and permission checks for non-logged-in users. The specific implementation is as follows:

<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;"> * Permission judgment method (don’t use this method yet, the system method used is extremely inefficient, wait until you have time to rewrite it)
</span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @param string/array $permission_name permission value (URL or permission name)/batch detection can be passed into the array
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @param int $user user id, if no value is passed, the current logged in user will be taken
</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @return boolen
</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;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</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;">Check if you have logged in</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;">empty</span>(<span style="color: #800080;">$permission_name</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 16</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</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;">empty</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;">Administrator permissions cannot directly return true, there will be administrator type = 1 points to people with non-administrator permissions (there is a pitfall)
</span><span style="color: #008080;"> 24</span>
<span style="color: #008080;"> 25</span> <span style="color: #008000;"> //Anonymous method, handles the situation when the administrator returns the value</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;"> return 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;"> }else {
</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 (empty($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 = "SELECT type FROM 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;">            return 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;">SELECT xc.child, xc1.child as role_name FROM xm_auth_assignment xa 
</span><span style="color: #008080;"> 67</span> <span style="color: #000000;">            INNER JOIN xm_auth_item_child xc ON xa.item_name = xc.parent
</span><span style="color: #008080;"> 68</span> <span style="color: #000000;">            LEFT JOIN xm_auth_item_child xc1 ON xc.child = xc1.parent
</span><span style="color: #008080;"> 69</span>             WHERE 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;">empty</span>(<span style="color: #800080;">$permission</span><span style="color: #000000;">)) {
</span><span style="color: #008080;"> 75</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</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;">Combined permission list</span>
<span style="color: #008080;"> 79</span> <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$permission</span> <span style="color: #0000f"></span>
Copy after login
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!