1.4.2 入口文件(1)
本节首先介绍系统多个请求入口设计带来的不便,然后介绍单一请求入口设计模式实现原理。本节的学习目标是明确单一入口文件设计模式的优点,避免在以后的开发项目中出现多入口。
1.入口文件设计
系统中凡是能够被访问的PHP文件称为入口文件。如果用户的不同请求直接对应到Web服务器中的不同PHP文件,即系统是多入口设计。在刚开始学习PHP的时候,通常一个项目都会这样做:
index.php ——网站首页
list.php?page=5 ——内容列表页
info.php?id=12 ——内容详细页
login.php ——用户登录页
又或者在1.4.1节实现MVC框架模式后,访问不同的控制器类文件,如DefaultController. php或SiteController.php。
对于这些项目来说,都有多个入口文件,随着项目规模的不断扩大,多入口的设计缺陷会越来越明显,如系统目录结构混乱,后期维护困难,容易暴露程序漏洞,不便于系统的统一管理等。为了避免多入口设计带来的诸多问题,可以使用单一入口设计模式。单一入口设计模式就是一个文件处理所有的HTTP请求,也就是说,访问任何控制器文件,无论是DefaultController.php、SiteController. php,还是其他控制器类文件。每一次请求都是指向服务器的同一个文件,如入口文件index.php,该文件负责URL解析,最终转向所要访问的页面,如图1-6所示。
PHP单一入口模式可谓是现在一种比较流行的大型Web应用开发模式。当前比较流行的一些PHP开发框架,如Zend、ThinkPHP和Yii等都是采用单一入口模式。
使用单一入口文件模式的优点如下。
更加安全。单一入口模式给用户提供了单一的请求入口,在入口文件可以对请求进行过滤,加入安全处理代码,而传统的多请求入口模式需要为每个文件都加入安全处理程序块。
模块化程度高。开发人员只需关注自己所开发的模块,开发人员之间不需考虑程序是否正常运行,因为这一切全部交给入口文件来协调。
便于统一管理,定制性强。系统的所有模块都由入口文件进行统一管理,任何一个模块可以不经模块本身启用或禁用。
2.入口文件中实现URL的解析
在上文中提到入口文件的URL解析,即入口文件会将原始请求转发给相应的处理控制器,完成具体的业务处理。例如,有以下URL地址:
- http://<hostname>/
- http://<hostname>/index.php
- http://<hostname>/index.php?r=site
- http://<hostname>/index.php?r=site/index
自定义框架模仿Yii框架采用路径(PATH)URL模式访问规则。路径URL模式采用目录分层的思想,路径格式简洁,URL解析效率高,此URL格式为:http://<hostname>/appname/index.php?r= controllerID/actionID
我们希望上面所有URL被解析后都会访问SiteController控制器的actionIndex()方法。URL解析执行流程如图1-7所示,首先访问入口文件,在其中分析请求URL的参数,在没有“r”参数的情况下默认访问SiteController的actionIndex()方法,否则依据“r”参数访问SiteController的actionIndex()方法,即所有的访问由URL的参数来统一解析和调度。
入口文件index.php中代码实现如下。
- <?php
- //默认控制器是SiteController
- $defaultController="site";
- //默认动作actionIndex
- $defaultAction="index";
- //如URL 为http://hostname/index.php?r=controllerid/actionid
- //得到controllerid/actionid
- if(!empty($_GET['r']))
- {
- $route=$_GET['r'];
- //得到controllerid 赋值给成员变量
- $pos=strpos($route,'/');
- $defaultController=substr($route,0,$pos);
- $defaultController=strtolower($defaultController);
- //得到actionid 赋值给成员变量
- $defaultAction=(string)substr($route,$pos+1);
- }
- //得到控制器类名
- $className=ucfirst($defaultController).'Controller';
- //获得控制器文件路径
- $classFile="./controllers/".$className.'.php';
- //最后一步操作:该类文件存在则导入,该类存在则创建对象并调用acion 方法
- if(is_file($classFile))
- {
- if(!class_exists($className,false))
- {
- require($classFile);
- $class= new $className();
- $functionName="action".ucfirst($defaultAction);
- $class->$functionName();
- }
- }
- ?>
由上面的程序可知,默认的控制器是SiteController,默认的执行方法是actionIndex()方法。控制器的类名首字母大写,以“Controller”结尾,而且控制器类文件必须保存在controllers文件夹中;动作方法名必须以“action”为前缀,acitonID首字母大写。从这段程序中也可以了解到代码规范的重要性,因为文件名或类名等都会在程序中使用。同样的道理,在将要学习的Yii框架开发过程中,也要遵守一定的编码规范。例如,命名类时,使用驼峰风格,即每个单词的首字母大写并连在一起,中间无空格;变量名和方法名应该使它们的第一个单词全部小写,其余单词首字母大写,以使其区别于类名,如$basePath、runController();对私有类成员变量来说,推荐以下画线作为其名字前缀,如$_actionList。
提示:
为了使PHP语言开发的框架能够遵循共同的编码风格,在2009年由几个框架的开发者组成了PHP-FIG(PHP Framework Interoperability Group)小组,一直扩展到现在已经拥有20多位成员。
实现入口文件后,框架执行流程如图1-8所示。
1.用户发出了访问URL的请求,Web服务器通过执行入口文件index.php处理此请求。
2.入口文件负责完成URL的解析,根据URL请求创建控制器并调用动作处理用户请求。
3.控制器调用模型实例对象从数据库中读取数据。
4.渲染视图。
5.视图读取并显示模型的数据。
6.动作完成视图渲染并将其返回给用户。
3.单一入口模式服务器环境配置
实现单一入口模式之后,需要确保应用根目录下,除入口文件外的PHP文件(所有安全敏感的PHP文件)都不允许访问。通过实践证明,使用Apache服务器的目录级配置文件.htaccess文件保护目录比使用其他方式更为有效和安全。更重要的是,使用.htaccess的方式进行设置,不需要编写程序就可以实现,具体操作比较容易。
(1)目录级配置文件.htaccess
.htaccess是一个纯文本文件,其中存放着Apache服务器配置相关的一些指令,它类似于Apache的站点配置文件,如httpd.conf文件。.htaccess与httpd.conf配置文件不同的是,它只作用于此目录及其所有子目录。另外,httpd.conf是在Apache服务启动的时候就加载的,而.htaccess只有在用户访问目录时加载,其中,修改.htaccess文件不需要重启Apache服务器。.htaccess的功能包括设置网页密码、设置发生错误时出现的文件、禁止读取文件、重新定向文件等。
在需要针对目录改变服务器的配置,而对服务器系统没有root权限时,应该使用.htaccess文件。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是在一台机器上提供多个用户站点,而又期望用户可以自己改变配置的情况下,一般会开放部分.htaccess的功能给使用者自行设置。
注意:
.htaccess是一个完整的文件名,不是***.htaccess或其他格式。
如何允许用户使用.htaccess文件呢?在Apache服务器的配置文件httpd.conf中,查找服务器的根目录的配置信息:
- <Directory "e:/wamp/www/">
- ……
- AllowOverride None
- ……
- </Directory>
喜欢的朋友可以添加我们的微信账号:
51CTO读书频道二维码
51CTO读书频道活动讨论群:365934973