0

0

ThinkPHP控制器学习(一)

php中文网

php中文网

发布时间:2016-06-20 12:27:16

|

1126人浏览过

|

来源于php中文网

原创

星空

多层控制器的使用

TP3.23对控制器做了更加细致的分层,除了默认的Controller层,还可以自定义事件控制层Event。

建立的方法是:

立即学习PHP免费学习笔记(深入)”;

在模块第一级目录,即Controller层的同级目录,新建文件夹Event 在Event文件夹中,新建文件 AdminEvent.class.php 在新建文件中输入代码
namespace Admin\Event;// use Think\Controller;  // 如果不使用到controller的功能 // 可以不用添加该命名空间引用 也不用继承controllerclass AdminEvent extents Controller {    public function test() {        echo 'Hello World !';    }}

系统默认的控制器(即访问控制器)是Controller,因此在浏览器输入http://localhost/forum/index.php/Admin/admin/test是无法进行访问的,Event控制器仅在内部方法方法中进行访问。当然可以通过DEFAULT_C_LAYER来修改访问控制器的名称。但建议不这么做。

定义了事件控制器,对系统模块的构建有很大的好处。可以将浏览器的请求与内部事件处理相隔离,使整个业务逻辑看上去更为简洁明了。

如一个后台系统,有多个页面,都需要对用户是否登录进行检测,如果这个检测都在Controller进行的话,整个业务逻辑会显得很混乱,而且可能会有代码冗余。这时可以通过Event事件控制器来定义一个检测方法,然后在Controller层进行调用,这样代码不仅更为简练,业务逻辑也更为清晰。

Event控制器

namespace Admin\Event;use Think\Controller;      class AdminEvent extents Controller {    /**     *  登录检测  检测session中用户     *  @param    类型    参数名 含义     *  @return 类型       */    function checkLogin() {        $value = session('UserName');        if(!isset($value)) {            $this->error('请登录后访问' , U('admin/login'));        }    }}

Controller控制器

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    /**      *  后台首页面     */    public function index(){        A('Admin' , 'Event')->checkLogin();        $this->assign('title','后台');           $this->display();       }    /**     -  文章显示控制     -  @param       -  @return      */    public function article() {        A('Admin' , 'Event')->checkLogin();        $this->assign('title','文章-后台');                     $this->display();    }}

这样无论是从那种链接登入后台,都会进行用户检测,不仅提高了安全性,而且代码逻辑清晰。

我们可以将数据库添加操作在Event控制器中完成,在Controller控制器只进行模板输出,接受表单提交。以上。

初始化操作

在Think\Controller.class.php的构造方法中进行视图类实例化后,会检测是否存在一个_initialize方法。如果存在,就会事先调用该方法。

这就是控制器的初始化操作。在控制器类中定义_initialize方法,在操作其他方法之前都会先执行该方法。

如:

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    # 初始化操作    public function _initialize() {        echo '页面初始化,请等待<br/>';    }    # 主页    public function index() {        echo 'index';    }}

在浏览器输入http://localhost/forum/index.php/Admin,则会输出

页面初始化,请等待index

有了这个方法,我们上面所讲的登录检测就能够再次进行简化了。即在_initialize方法中进行是否登录的检测。但在_initialize添加了登录检测后,我们不能够将与登录有关的内容放入AdminController控制器中了,否则会不停的跳转到error页面,而无法显示登陆页面。

我们可以将登录与注册同时拿出,新建一个控制器,名字叫UserController。在这个页面进行登陆与注册功能,而error页面跳转到该页面。

UserController

namespace Admin\Controller;use Think\Controller;class UserController extends Controller {    /**     *  用户登录     */     public function login() {        echo '用户登录';     }    /**     *  用户注册     */    public function register() {        echo '用户注册';    }}

AdminController

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    # 初始化操作    public function _initialize() {        A('Admin' , 'Event')->checkLogin();    }    /**      *  后台首页面     */    public function index(){                   $this->assign('title','后台');           $this->display();       }    /**     -  文章显示控制     -  @param       -  @return      */    public function article() {                    $this->assign('title','文章-后台');                     $this->display();    }}

AdminEvent

namespace Admin\Event;use Think\Controller;      class AdminEvent extents Controller {    /**     *  登录检测  检测session中用户     *  @param    类型    参数名 含义     *  @return 类型       */    function checkLogin() {        $value = session('UserName');        if(!isset($value)) {            $this->error('请登录后访问' , U('user/login'));        }    }}

这样一个比较完善的后台登陆就完成了(当然还未实现具体的业务逻辑),比较最原始的方法,代码简洁清晰了很多,也完全符合MVC设计思想。

前置与后置

与初始化设置类似,TP提供了前置与后置操作,要进行前后置操作需要真实的方法,系统在执行该方法前会进行检测,如果定义了前后置操作,则会安照顺序进行。定义的方法是在执行方法前加入_before_或_after_,如

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    public function _before_index() {}    public function index() {}    public function _after_index() {}}

在访问http://localhost/forum/index.php/Admin的时候,就会先执行_before_index,在执行index,最后执行_after_index。注意的是如果在index中定义了断点方法,如die,exit,跳转方法error,success就不会继续执行_after_index。

这个前后置方法,我暂时还未想到有什么比较有用的地方,先写出来,以后想到了,在进行添加。

空操作与空控制器

按照ThinkPHP的URL命名规则(pathinfo模式),入口文件之后的操作成为

模块控制器操作

如http://servername/index.php/模块/控制器/操作/[参数名/参数值…]

空操作就是指系统找不到url指定的操作方法,此时就会报错,可以使用定义空操作方法来进行避免。如:

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    /**      *  后台首页面     */    public function index(){                   $this->assign('title','后台');           $this->display();       }    /**     -  空操作防止     -  @param    无     -  @return   无        */    public function _empty() {        $this->display('404');    }}

定义后,在输入错误的操作方法时,就会显示_empty中的内容。你可以定义一个404页面,在_empty中进行跳转。

空控制器

与空操作类似,访问不存在的控制器就会产生空控制器操作,避免该错误的方法是,在Controller中定义一个EmptyController控制器,在该控制器中同样定义_empty方法。

namespace Admin\Controller;use Think\Controller;class EmptyController extends Controller {    /**     -    空操作防止     -    @param    无     -    @return   无        */    public function _empty() {         $this->display('admin/404');    }}

404页面对于404页面的定制,如果没有特殊需求的同学,建议使用腾讯的404公益页面,只要嵌入一小段JS代码,就会跳转到腾讯的寻找失踪儿童的404页面。虽然可能和你的网站风格不统一,但是每多一个看见该页面的人,就可能加大找回一个失踪儿童的几率。一小段代码,献出一段爱心,你值得拥有。

// 腾讯404页面<script type="text/javascript" src="http://www.qq.com/404/search_children.js" charset="utf-8" homePageUrl="http://yoursite.com/yourPage.html" homePageName="回到我的主页"></script>

20160529162719.png

Action参数绑定

在说Action参数绑定前,先说说与之相关的问题。在学习Action参数绑定之前,我获取GET参数的方式是怎么样?自然是利用$_GET来获取URL上的参数,如:

# 我要点击一个文章链接,来进行文章编辑 url如下http://localhost/forum/index.php/Admin/admin/article/act/edit/aid/2# 然后通过$_GET来获取act aid得到参数,来判断进行的操作以及操作的文章idif($_GET['act'] == 'edit') {    # 文章编辑  利用 aid从数据库取出文章进行编辑}

这种方式虽然可行,却不够优雅,作为一个立志成为攻城狮的程序员来说,要想尽方法使你的代码更加简洁,更加优雅。

这时来看看Action参数绑定,什么是Action参数绑定?

SumiNote
SumiNote

一款服务留学生的AI学习神器

下载

Action参数绑定是通过直接绑定URL地址中的变量作为操作方法的参数, 可以简化方法的定义甚至路由的解析。

说的还挺绕,其实就是把GET形式传递的参数直接绑定到你的操作方法上,你就能够直接访问,而不用通过$_GET。举个例子,还是上面的链接http://localhost/forum/index.php/Admin/admin/article/act/edit/aid/2。定义操作方法如下:

namespace Admin\Controller;use Think\Controller;class AdminController extends Controller {    /**      *  文章显示控制器     *  @param:$act   string   进行的文章操作  默认值空 -> 显示所有文章     *  @param:$aid   int      文章的主键id    默认值0  -> 显示所有文章     */    public function article($act='' , $aid = 0) {        if(empty($act) || empty($aid) ) {            # 显示所有文章        } else {            # 进行想要的操作            echo '你要进行的操作是'.$act.',你想要'.$act.'的文章id是'.$aid;        }    }}

访问上面的链接,结果为

你要进行的操作是edit,你想要edit的文章id是2

这就是Action参数绑定。要使用这种方式需要开启URL_PARAMS_BIND设置(默认设置true)。

Action参数绑定有两种形式

按照变量名绑定 按照变量顺序绑定

将URL_PARAMS_BIND_TYPE的值设置成0,按照变量名绑定,设置成1,按照变量顺序绑定。

按照字面意思也可以理解,按照变量名绑定即寻找get参数时,按照操作方法中定义的变量名去寻找相应的值。如果没有就报错。这也是最常用的方式。

按照变量顺序绑定,即按照url上get参数的顺序去给操作方法上的变量赋值,这样在url上的参数就能够随意变换位置,同时url上get参数也可以隐藏变量名。

举例说明一下:

按照变量名绑定链接 http://localhost/forum/index.php/Admin/admin/article/act/edit/aid/2 那么打印出来的结果

你要进行的操作是edit,你想要edit的文章id是2

链接 http://localhost/forum/index.php/Admin/admin/article/aid/2/act/edit 那么打印出来的结果

你要进行的操作是edit,你想要edit的文章id是2

可以看出无论怎么变换位置,得到的结果是一样的。

按照变量顺序绑定链接 http://localhost/forum/index.php/Admin/admin/article/edit/2 那么打印出来的结果

你要进行的操作是edit,你想要edit的文章id是2

链接 http://localhost/forum/index.php/Admin/admin/article/2/edit 那么打印出来的结果

你要进行的操作是2,你想要edit的文章id是edit

因此如果采用变量顺序绑定时,一定要确保url上的get参数顺序与操作方法上的参数顺序一致。

值得注意的是按照变量名绑定仅对类似于pathinfo方式的地址有效。如pathinfo模式与兼容模式。

伪静态

伪静态是相对于静态页面来说的,主要是为了更好的SEO效果,并不是真正的静态,而是在URL的结尾添加了类似html,htm等的后缀。在TP中默认是开启伪静态的。可以通过URL_HTML_SUFFIX来设置静态的后缀名,如:

'URL_HTML_SUFFIX'=>'shtml'

访问:

http://localhost/forum/index.php/Admin/admin/article/2/edit.shtml

就是有效的,而访问.html则会报错。也可以设置多个静态后缀,使用**|**来进行分割。

// 多个伪静态后缀设置 用|分割'URL_HTML_SUFFIX' => 'html|shtml|htm'

也可以对某些后缀进行禁止访问,利用URL_DENY_SUFFIX

'URL_HTML_SUFFIX' => 'html'

设置后就不能访问任何以html为后缀的url。可以将URL的模式改成rewrite模式来配合伪静态,否则一个链接上既有.php,也有.html看上去很别扭。

注意:使用伪静态模式必须开启httpd.conf的mod_rewrite.so模块。

rewire模式切换

开启rewrite模式需要配合修改apache的重写内容。

打开httpd.conf文件,搜索mod_rewrite.so,将该模块前面的#删除。然后新建.htaccess,放入如下代码:

<IfModule mod_rewrite.c>    RewriteEngine on    RewriteCond %{REQUEST_FILENAME} !-d    RewriteCond %{REQUEST_FILENAME} !-f    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]</IfModule>

保存到项目入口文件同级目录。重启apache即可。

apache的部分重写规则

实现伪静态多数是利用apache的URL重写规则(RewriteRule),我不是很懂RewriteRule,只是从网上找来了一些资料。上述代码中,RewriteEngine表示是否开启重写引擎,RewriteCond重写应用条件,RewriteRule表示重写规则。从代码中明显看出,利用了正则表达式的功能。

正则表达式含义

表达式 含义 表达式 含义
0-1个字符 $ 段落结束字符
. 1个字符 \ 转移字符
* 0-x个字符 取反
+ 1-x个字符 () 内存限定传值
^ 段落开始字符 [0-9] 所有数字字符
[a-z] 所有小写字母 [A-Z] 所有大写字母
{n} 重复n次 {n,} 重复n次或更多次
{n,m} 重复n到m次

在被匹配的字符串中$N表示与表达式中第一个()进行匹配,上述代码中RewriteRule中的$1就表示与表达式中的第一个()进行匹配,这样所有index.php/都会被其他字符或空字符匹配。

RewriteRule我确实不怎么懂,网上的资料也很乱,就不多写了,英语好的同学去看官方文档吧。

总结

今天关于控制器的学习就写到这里,还有很多想要说的,但没必要都一一赘述。下次会将阅读源码的一些想法写出来。最后想吐槽一下,简书关于PHP的程序员好像很少,每次找很长时间才能看见一篇关于PHP的,醉了醉了。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

ECMAScript6 / ES6---十天技能课堂
ECMAScript6 / ES6---十天技能课堂

共25课时 | 2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号