🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
https://blog.csdn.net/niuniuasb/article/details/60959029 1、当你 require ThinkPHP之后,会自动在App目录下生成 common, Home, Runtime 三个文件夹。 2、输入网址 http://localhost/blog/app/index.php/home/index/index 出现 ~~~ 无法加载控制器:index 错误位置 FILE: D:\xampp\htdocs\blog\ThinkPHP\Library\Think\App.class.php  LINE: 90 ~~~ 原因解析:默认情况下是大小写敏感,为了方便,我们可以更改设置: ~~~ <?php return array( //url 地址大小写敏感设置 'URL_CASE_INSENSITIVE' => true, ); ~~~ 3、新建一个控制器,注意命名空间,以及继承等。 ~~~ <?php namespace Home\Controller; use Think\Controller; class UserController extends Controller{ function login(){ $this -> display(); } } ~~~ 4、当写好控制器后,我们需要添加相应的视图文件。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221102613335-1771708786.png) 5、连接数据库。对于数据库的连接,我们同样需要更改设置。这里我们使用的是mySQL,具体如下图所示。如果使用的端口号是默认的,密码为空,就不用填写。注意数据库的名字和前缀。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221103231570-1812616255.png) 6、在对数据库进行操作之前,我们得先建一个 Model 类,方面和后续的使用。我们在和Home同目录下新建一个 Model 文件夹,写好代码。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152156210-1402054729.png) 7、然后我们开始调用 Model 来操作数据库,输入网址,看到下面的内容就可以知道连接数据库成功了。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152312366-833420477.png)![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152435241-2070099152.png) 8、接下去,我们把之前写好的前端和后台的html等文件都放进来,为了方便后续的操作,我们要对文件进行分类,最终效果如下所示: ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152819241-166954367.png)   ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221153107288-2033869153.png)   ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152905648-874242955.png)   ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221152927679-1695762955.png) 其中public 存放一些样式,js文件,图片等。 9、如果我们要访问这些 html 文件的话,还必须添加相应的控制器等。输入网址,访问,我们会发现页面缺少图片和样式。由于 css, js 文件位置的变动,我们必须重新修改这些 url 或者 src 属性。因为这些文件经常用到,所以我们添加了常量,并在html文件中进行修改。这样我们就能看到最终的页面了。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221160201351-1412114311.png)  ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221160327554-1115358088.png) 10、采用 Smarty 模板。 这时候只需要更改设置就好。 ![](http://images2015.cnblogs.com/blog/916005/201702/916005-20170221162334913-1750513590.png) 11、下面我们开始演示注册模块,这里面涉及很多内容。 首先我们编写一个注册用的 Model, 主要是用来验证数据。 ~~~ <?php namespace Model; use Think\Model; class UserModel extends Model{ protected $patchValidate = true; //批量验证 protected $_validate = array( array('username','require','用户名必须!'), //默认情况下用正则进行验证 array('password','require','password必须!'), array('password2','password','两个必须相等',0,'confirm'), array('user_email','email','邮箱格式错误',0), ); } ~~~ yu 与此同时我们还需要在控制器上编写相应的代码。太长了,不截图,还是放代码实在 ~~~ <?php namespace Home\Controller; use Think\Controller; class UserController extends Controller { function login(){ $this -> display(); } function register(){ // 调用UserModel $user = new \Model\UserModel(); if(!empty($_POST)){ $z = $user -> create(); if(!$z){ var_dump($user -> getError()); } // 把数据添加到数据库中去 $rst = $user -> add(); // 判断是否添加成功 if($rst){ echo "success"; }else{ echo "error"; } } $this -> display(); } } ~~~ 12、登陆模块。用户登录的时候,需要对用户名和密码进行判断,为了防止 sql 注入攻击,我们首先通过用户名查询存不存在这条数据,然后再来比对密码是否匹配。当然实际上保存的密码应该是加密后的,此处为了方便,没有对密码进行加密。此外,除了用户名密码,还有验证码的,因此还需要对验证码进行设置,比如多少位啊,有没有背景图片,宽和高的长度啊等。具体见如下代码。 为此,我们编写了一个 Model, 内部有一个函数,用来查询用户名密码是否正确。 ~~~ <?php namespace Model; use Think\Model; class ManagerModel extends Model { function checkNamePwd($name, $pwd){ $info = $this -> getByMg_name($name); var_dump($info); if($info != null){ if($info['mg_pwd']!= $pwd){ return flase; }else{ return $info; } }else{ return false; } } } ~~~ 同时存在一个对应的控制器,主要是对验证码的设置与检验,以及对用户名和密码判断,判断正确后可能会进行跳转等等。 ~~~ <?php namespace Admin\Controller; use Think\Controller; class ManagerController extends Controller{ function login(){ //var_dump($_POST); if(!empty($_POST)){ // 首先检查验证码是否正确 $verify = new \Think\Verify(); if(!$verify -> check($_POST['captcha'])){ echo "验证码错误"; }else{ // 在 Model 里面制作一个专门方法进行验证 echo "343"; $user = new \Model\ManagerModel(); // 此处调用 Model 中的函数进行检查 $rst = $user -> checkNamePwd($_POST["mg_username"], $_POST["mg_password"]); if($rst ===flase){ echo "用户名或密码错误"; }else{ // 保存在 session 中 session('mg_username',$rst['mg_name']); session('mg_id', $rst[mg_id]); // session (null); 清空全部; $this -> redirect('index/index', array('id'=>100, name=>'tom')); } } } $this -> display(); } // 验证码设置 function verifyImg(){ $config = array( 'useImgBg' => false, // 使用背景图片 'fontSize' => 16, // 验证码字体大小(px) 'imageH' => 40, // 验证码图片高度 'imageW' => 100, // 验证码图片宽度 'length' => 1, // 验证码位数 ); $verify = new \Think\Verify($config); var_dump($verify->entry()); } } ~~~  13、缓存设置。使用原理,对于某些常用的数据,我们可以进行缓存,还有对于数据库中变化不快的数据,也可以进行缓存。第一次先从数据库中获取,然后放入缓存中,设置有效期。下次访问的时候,就不用从数据库进行查询了,直接从缓存获取。 ~~~ function y1(){ var_dump($this -> y2()); } function y2(){ //被其他方法调用,获得指定信息 $info = S('goods_info'); if($info){ return $info; }else{ // 没有缓存就从数据库获取数据 $dt = "apple5s".time(); S('goods_info',$dt,10); return $dt; } } ~~~ y2 是通用方法,之所以不直接在 y1 里写,是因为,有时候可能不止只有 y1 需要, 其他函数也会用到,因此,我们就将其放在 y2 里面。 14、附件上传。 15、基于角色的访问权限控制 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305183829173-2016497917.png) 对角色进行权限划分        员工直接面对角色、角色直接面对具体操作权限        新员工入职只需要确定其角色,他的权限就由角色来确定        员工\-------------角色\--------------操作权限        现在权限分配非常容易,也非常科学        新员工入职公司只需要把其角色划分好,它的权限有角色确定 sw\_manager 后台用户管理员表 sw\_role     角色表 sw\_auth     具体权限表 1.      数据模拟 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305184845876-1210248844.png) ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305184753610-1324220960.png) ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305185116266-1387095711.png) 2. 通过已经模拟好的数据进行相关程序开发 a)  用户登录系统,左边显示权限按钮会根据具体角色显示 b)  在左边(Admin/Index/left)显示对应的权限信息 * 用户登录系统显示权限信息$\_SESSION\[‘mg\_id’\] * 根据session信息获得角色role\_id信息 * 根据角色id信息获得权限列表ids信息 * 根据权限ids信息查询具体权限信息进而显示 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305185335282-770392056.png) 虽然给用户及角色分配了权限,也实现对应的权限的显示 但是用户可以通过显示修改url地址达到访问其他权限的目的 **解决:**        每次用户访问的控制器和方法都需要和对应的角色里边的ac信息进行比较        ac信息里边存在这个控制器和方法就允许访问,否则禁止访问   **     技术角度:** 在每个控制器被实例化执行的同时就判断当前的控制器和方法是否允许角色访问 为了程序维护方便,给普通控制器制作父类控制器,在父类控制器的构造方法里边做控制器和方法的过滤工作。 普通控制器引入新的父类AdminController, 1.  在新父类控制器AdminController里边实现每次访问控制器和操作方法过滤 a)  具体限制分三种情况 * 自定义方法不进行权限限制(Index/head  left  right   Manager/login) * 系统管理员也不进行权限限制 * 当前用户允许访问的权限就是角色对应的权限 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305185706141-1799395492.png)  16.角色维护 Admin/Role/showlist   显示角色信息 把许多复选框的权限表单的信息收集起来保存到角色的数据表中 在设置权限的时候,把已经有的权限给显示出来(复选框有被选中) 当前角色知道,当前角色对应的权限ids也知道,也可以把ids由字符串变为数组 遍历权限的时候把id与ids的数组做比较,判断是否是其中的一个元素,进而设置checked属性  in\_array() 1.      制作表单显示具体被分配权限信息 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194658470-1972124810.png) 2.      收集权限信息在RoleModel模型里边保存 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194728016-337632919.png) 3.      分配权限时候,已经有的权限,复选框需要被选中 ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194745407-449481083.png)  4.      展示分配权限信息的表单对应控制器部分: ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194800907-428286771.png) 17、权限维护 展示、添加权限 AuthController function showlist() function  add() 1. 展示权限信息,及名字设置缩进关系字样       ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305195056454-447432592.png) 2. 添加权限 3\. 优化        ① 添加权限父级只显示level=0 或level=1        getInfo传递不同参数,获得的信息也略有差异       ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194929766-2022118732.png)        ② 为角色分配权限,显示三级权限        ![](http://images2015.cnblogs.com/blog/916005/201703/916005-20170305194939891-467976516.png)       18、【管理员列表实现】 Manager/showlist 总结: 1.      通过角色分配权限维护 2.      维护权限数据,添加权限 a)      auth\_path b)       帮组我们对数据进行排序显示 c)       全路径:父级的全路径和本身id结合的信息 d)      auth\_level e)       基本: 3\. 维护管理员数据,角色信息( {html\_options} )