ThinkPHP教程_PHP框架之ThinkPHP(二)【URL路径访问与模块控制器、URL四种模式、PATHINFO的两种模式、模板与控制器之间的关系】

一、URL路径访问与模块控制器

  URL  模块(控制器)  动作(方法)

  即以上三者之间的关系URL:http://127.0.0.1/projectName/index.php/模块/动作

  1、ThinkPHP规定,两点

    ·第一、所有的主入口文件默认访问index控制器(模块)

    ·第二、所有的控制器默认执行index方法(动作)

  特别强调一下,以上两点是独立的!也就是说"所有的主入口文件默认访问index控制器,并执行默认执行index方法"是不准确的

  那么,http://127.0.0.1/projectName/index.php(即使没有指定模块和动作)会执行index控制器中index方法,就理所当然咯!

  2、(自定义)控制器命名规范

  举个例子,用户管理控制器(模块)  UserAction.class.php  模块名称Action.class.php,且模块名称首字母必须要大写

  

  上面是文件名命名规范,同时还要注意类名要与文件名一致,即UserAction.class.php其中的类名称必须是UserAction。同时注意这个类必须继承Action类

  

  3、只有模块中的public方法才能被访问,protected和private方法都是不能被访问的

  显然这比较好理解,因为本质上在入口文件中是有$userAction=new UserAction;$userAction->方法名();这两条语句的

  那么,在控制器中定义一个private方法有和意义呢?结果是很有必要的,因为对于一个模块中的一个动作,可能由于某一个动作比较复杂,需要执行的代码比较多,或者某一个动作安全性要求比较高,那么就需要将一部分代码或安全性比较高的代码写到本模块的另外一个private方法中,然后在该动作(方法)内调用,这样的话,可以简化代码,使得代码看起来更有条理,同时还比较安全!

  

  还有一种情形就是在一个模块中,可能有一段代码是各个动作(控制器)公用的,那么也可以这段公用的代码封装到一个private方法中,然后供模块内其它动作调用!可能有人要问了,既然是公用的,那么为啥不写到项目目录->Common目录中的一个函数文件中去呢,对于此,个人理解是项目目录->Common目录中的函数是所有模块公用的,而这里是一个模块中的各个动作公用的,点到为止咯!

  4、ps,在实际项目开发过程中,最好将(自定义)控制器(或模型)的各个名称映射成中文(或英文)写入到一个文档中,同时说明这些控制器(或模型)中都有哪些方法,且这些方法的作用,既便于他人阅读也便于自己回顾!

二、URL的四种模式

  ThinkPHP支持的URL模式包括普通模式PATHINFO模式REWRITE模式兼容模式,都提供路由支持。默认为PATHINFO模式,提供最友好的用户体验(即方便人看)和搜索引擎友好支持(SEO,即方便搜索引擎查)!分别标号为0、1、2、3,可在项目目录->Conf目录->Config.php文件中进行修改

  1、普通模式

  http://127.0.0.1/projectName/index.php?m=moduleName&a=actionName&id=1

  2、PATHINFO模式

  http://127.0.0.1/projectName/index.php/moduleName/actionName/id/1

  注意,在PATHINFO模式下GET传值就不能用普通模式的&id=1的这种格式了,即http://127.0.0.1/projectName/index.php/moduleName/actionName&id=1,因为如果这样写,系统会误认为actionName&id=1整体是一个动作名称!

  在默认的PATHINFO模式下,如果URL是按照普通模式书写的,那么也会自动变成PATHINFO模式的格式!然后这一点在我的环境中没有测试出来,额...

  3、REWRITE模式

  重写模式,与伪静态有关

  可以自己写相关的rewrite规则,也可以直接使用ThinkPHP提供的rewrite规则,如果使用ThinkPHP提供的rewrite规则,则为

  http://127.0.0.1/projectName/moduleName/actionName/id/1

  注意,要想开启REWRITE模式之前,得先做两个操作

    ·第一、开启web服务器的rewrite模块,拿Apache为例,在Apache主目录->conf目录-httpd.conf文件中将如下图所示语句前的#去掉。IIS、Nginx自行参考文档哈

    

    ·第二、在入口文件平级的目录创建一个.htaccess文件,然后将如下内容copy到.htaccess文件中保存即可!至于为啥要叫.htaccess这个名字,因为Apache规定的!下面还补充了一点如何在Windows下创建一个.xxx格式 名称的文件

    

       

  REWRITE模式下,PATHINFO模式的URL也是可以识别的,但是如果没有开启REWRITE模式,REWRITE模式的URL是不能识别的!

  有兴趣的可以参阅Apache手册中的URL重写指南部分进一步了解URL重写

  4、兼容模式

  http://127.0.0.1/index.php?s=/moduleName/actionName/id/1

  当服务器不支持PATHINFO模式时,如果整个项目的所有URL又都是采用的PATHINFO模式进行书写的,那么就会出现路径不存在的错误!这是显然的嘛,服务器压根就不认识你的URL,怎么搞对不对?然而重新把项目中所有的URL都改成普通模式又太过繁琐,所以ThinkPHP设计者就设计了兼容模式,也就是说项目中开起了兼容模式(config.php中配置为3),即使服务器不支持PATHINFO模式,也能识别PATHINFO模式的URL!

三、PATHINFO的两种模式

  PATHINFO本身也有两种模式,分别为普通模式智能模式(智能识别模块和动作)

  1、普通模式

  必须指明模块和动作,即http://127.0.0.1/projectName/index.php/m/moduleName/a/actionName/id/1。而且既然指明了模块和动作,那么动作和模块的顺序是可以颠倒的

    ·设置

    同样是在项目目录->Conf目录->config.php中进行设置,"URL_PATHINFO_MODEL"=>1

  2、智能模式

  不必指明模块和动作,默认模式,在【二、URL的四种模式】中就是按照智能模式来的!所谓智能识别模块和动作,就是将URL中紧跟在入口文件的第一个参数作为moduleName,第二个参数作为actionName,显然,此时动作和模块的顺序就不能颠倒了

    ·设置

    同样是在项目目录->Conf目录->config.php中进行设置,"URL_PATHINFO_MODEL"=>2

  注意,不管是普通模式还是智能模式,GET传值都必须是键/值这种格式,即都要指明键

  "URL_PATHINFO_DEPR"=>"-"设置可以修改分隔符(默认为/),即http://127.0.0.1/projectName/index.php/m-moduleName-a-actionName-id-1,同样,这个设置对于普通模式和智能模式都生效

  "URL_HTML_SUFFIX"=>"html"设置可以加上.html后缀,更好的支持SEO,即http://127.0.0.1/projectName/index.php/m-moduleName-a-actionName-id-1.html

四、模板与控制器之间的关系

  首先得知道,应用模板都必须放在应用目录->Tpl目录->default目录下,注意,default目录是在应用初始化时自动生成的,同时可以在Tpl目录下自定义目录,说白了就是自定义皮肤,而default目录就是应用默认皮肤,在自定义目录下,当然也是可以放模板的!

  

  其次,要在各个皮肤目录下都要针对项目模块建立相应的目录,并在建立的目录中针对模块动作创建相应的模板

  

  

  

  

  

  最后,要知道调用模板的操作($this->display();)是发生在模块的动作中的

  1、有了上述三点,再来具体说说$this->display();

  如果没传值,则调用的是默认皮肤目录中的针对当前模块的目录中的针对当前动作的模板,比如说

  

  有的小伙伴可能有些疑问了,UserAction这个类中并没有定义display()方法呀,怎么可以直接用display()呢?额,被忘了后面的extends Action呦!对,display()就是Action这个类中的一个方法!

  如果传值,则有几种情况,ps,传值的话,对于模板名,只需要写.html后缀之前的名称,即对应的动作名

    ·调用当前模块的其它动作模板

    $this->display("当前模块的其它动作名");

    ·调用其它模块的动作模板

    $this->display("其它模块名:动作名");其实,严格来说,这里的模块名和动作名指的实际上是default皮肤目录下的一个目录名及其下面的一个文件名而已,并不是非得要求Action目录中有该模块及其动作,而只需要在Tpl目录->default皮肤目录下有叫"其它模块名"的目录并且在其下有一个叫"动作名"的模板文件即可!

    ·调用其它皮肤的模板

    $this->display("皮肤名@模块名:动作名");

    ·直接通过路径调用模板

    $this->display("模板路径");模板路径既可以是相对路径也可以是绝对路径,不过要注意的是,如果是采用相对路径,则必须是相对于入口文件

    其实,在这里要说明的是,实际上,前三种情况,在底层还转化成了路径的,而皮肤名、模块名、动作名实际上指是目录和文件名

  以上只说了display()方法的第一个参数,而display()方法还有两个参数,分别是"模板编码"(指定模板输出编码)、"模板格式"(指定模板输出格式(text/html或text/xml))!

  2、$this->assign()

  $this->assign("模板变量名","值或变量");

  这里提一下修改模板标签定界符,ThinkPHP自带模板引擎的定界符默认是{},而默认定界符是会和模板中js代码及内联css冲突的,所以通常在实际开发中,都会修改模板标签的定界符,修改应用配置文件如下

  

  3、模板调用大小写问题

  开启调试模式后,ThinkPHP就会模拟Linux下的对文件名区分大小写,但是经过测试,发现只对文件名大小写敏感,而对文件夹名大小写不敏感

  

  

  

  

  

  同时,也验证了上面的那句话,即【其实,在这里要说明的是,实际上,前三种情况,在底层还转化成了路径的,而皮肤名、模块名、动作名实际上指是目录和文件名

  其实在测试过程中,还发现了一个问题,即加载模块执行动作的操作并不区分大小写,因为如果是加载模块或执行动作出错,报的是如下错误

  

  

posted on 2016-08-21 10:49  Yang24556  阅读(9634)  评论(2编辑  收藏  举报

导航