一、空操作和空控制器处理

空操作:没有指定的操作方法;空控制器:没有指定控制器,例如:

http://网址/index.php/Home/Main/login  正常

http://网址/index.php/Home/Main/hello 空操作(hello方法不存在)

http://网址/index.php/Home/beijing/login   空控制器(beijing控制器不存在)

1、空操作:

一般网站处于安全考虑不给用户提示任何错误信息

“空操作”本质意思:一个对象(控制器)调用本身不存在的方法

在OOP里边,对象调用本身不存在方法,处于用户体验比较好的角度考虑,我们可以在类里边制作一个魔术方法:function __call();

在tp里面控制器的父类:/tp/ThinkPHP/Library/Think/Controller.class.php,其中有个方法:

所以空操作有两种解决方案:

(1)    在对应的控制器里边制作一个方法,名称为”_empty”,这个控制器的空操作都会自动执行该方法。(推荐使用)不要在父类中建,要在子类中建。

  1. function _empty()
  2. {
  3. echo "<h1>网页不存在,请检查浏览器地址信息!</h1>";
  4. }

这样在访问该控制器下空操作时:

(2)    给空操作制作一个同名的模板出来,系统会自动调用,例如:Home/Main/hello.html

  1. <body>
  2. <h1>别乱访问!</h1>
  3. </body>

这样在访问该空操作时:

但是这种方法仅限于这一个空操作,若是访问别的空操作,还是会有错误信息,由于空操作的不确定性,所以不推荐使用,知道这种方法就行。

2、空控制器

空控制器:在实例化控制器对象的时候,没有找到指定的类。

在ThinkPHP/Library/Think/App.class.php内部包括控制器对象创建,以及对象调用指定的方法呈现内容:

空控制器处理方案:可以再制作一个控制器:Home/Controller/EmptyController.class.php

在该控制器内部其实只需要制作一个_empty()方法即可:

  1. <?php
  2. namespace Home\Controller;
  3. use Think\Controller;
  4. class EmptyController extends Controller
  5. {
  6. function _empty()
  7. {
  8. echo "<h1>访问的页面不存在!</h1>";
  9. }
  10. }

这样再次请求:

二、跨控制器调用方法

例如:在Main控制器里面调用Index控制器中的ShuChu方法

Index控制器:

  1. <?php
  2. namespace Home\Controller;
  3. use Think\Controller;
  4. class IndexController extends Controller {
  5.  
  6. public function ShuChu()
  7. {
  8. return "教务管理系统";
  9. }
  10. }

控制器是一个类,要调用里面的方法,先要实例化对象,再通过对象去调用方法,这里有3中方法可以实现:

  • new的方式造对象,然后调用ShuChu方法
  • 使用A方法快速创建对象,相当于new的方式,比较方便,推荐使用
  • 使用R方法,不仅可以造对象,还能调用方法

Main控制器:

  1. <?php
  2. namespace Home\Controller;
  3. use Think\Controller;
  4. class MainController extends Controller
  5. {
  6. function ShuChu()
  7. {
  8. //跨控制器访问操作(方法) 因为控制器都是类,所以可以实例化对象来调用里面的方法
  9. //1.
  10. //造对象
  11. $index = new IndexController();
  12. //调用方法
  13. echo $index->ShuChu();
  14. //2.
  15. //使用A方法来快速创建对象
  16. $index = A("Index");
  17. echo $index->ShuChu();
  18. //3.
  19. //使用R方法,造对象,并且调用某一个特定的方法
  20. echo R("Index/ShuChu");
  21. }
  22. }

这样请求Main控制器中ShuChu方法:

三、跨模块调用

原来有一个Home模块,我们按照Home模块的规则新建一个Admin模块,里面的文件夹与Home模块一样:在JiaoWu/下新建Admin文件夹,在Admin/下新建五个文件夹:Controller/,Model/,View/,Common/,Conf/。在Controller/下新建TestController.class.php:

  1. <?php
  2. namespace Admin\Controller;
  3. use Think\Controller;
  4. class TestController extends Controller
  5. {
  6. public function Test()
  7. { return "Admin模块操作";
  8. }
  9. }

在Home/Main/ShuChu下调用Admin/Test/下的Test方法,只需在创建对象时前面加上模块名即可:

  1. <?php
  2. namespace Home\Controller;
  3. use Think\Controller;
  4. class MainController extends Controller
  5. {
  6. function ShuChu()
  7. {
  8. //跨模块调用方法
  9. //使用A方法
  10. $test = A("Admin/Test");
  11. echo $test->Test();
  12.  
  13. //使用R方法
  14. echo R("Admin/Test/Test");
  15. }
  16. }

这样访问ShuChu方法:

四、命名空间的定义及使用

我们正常管理文件使用文件夹,这是物理区分;

而命名空间相当于一个虚拟目录,虽然不在同一个文件夹下,但在虚拟目录下仍然属于同一类

TP框架的初始命名空间是:ThinkPHP/Library

在TP框架下的命名空间里面使用\代表的是初始命名空间(ThinkPHP\Library)

1.系统目录下根命名空间是以ThinkPHP/Library下面的文件夹名称,如:Think,Org

2.模块的根命名空间是以模块名命名的,如:Home,Admin

在定义命名空间的时候要从根写起,例如:namespace Home\Controller;       namespace Think\Model;

如果要使用某个类文件,引入该类命名空间的时候,使用use关键字,后面写该类的命名空间,后面加上“\文件名”,例如:use Think\Controller就是引入Think下的Controller.class.php类文件。

如果不想引入命名空间,在造类的对象的时候,可以使用\(初始命名空间)来找到对应的类,例如:new \Think\Page(30)

注意:命名空间使用的是反斜杠 \

五、视图(模板)

1.变量输出

与smarty类似,都是assign注册变量,然后在模板中使用<{ }>来标记使用变量

  1. function Test()
  2. {
  3. //注册变量
  4. $this->assign("a",10);
  5. $this->assign("b",20);
         $this->assign("pd",true);
  6. $this->assign("test","hello");
  7. $attr = array("one"=>100,"two"=>200,"three"=>300);
  8. $this->assign("shuzu",$attr);
  9. $this->display();
  10. }

在Test.html中:

  1. <div><{$test}></div>
  2. <div><{$shuzu["one"]}></div> <!--数组可以用索引,也可以用点语法 -->
  3. <div><{$shuzu.two}></div>

输出:

注意模板标签的<{和$之间不能有任何的空格,否则标签无效。

2.系统变量

系统变量的输出通常以<{$Think 打头,例如:

  1. <{$Think.session.user_id}> // 输出$_SESSION['user_id']变量
  2. <{$Think.get.pageNumber}> // 输出$_GET['pageNumber']变量

还可以输出常量:

  1. <div>__ACTION__</div> <br /> <!--系统常量有双下划线的直接写就可以,不用输出标记 -->
  2. <div><{$Think.const.MODULE_PATH}></div> <!--没有双下划线的,必须用$Think点出来,const可以不写 -->

输出:

输出配置参数使用:

  1. <{$Think.config.db_charset}>
  2. <{$Think.config.url_model}>

输出:

3.使用函数

调用函数使用“|”,后面跟函数名,例如:

  1. <{$data.name|md5} >

4.默认值输出

我们可以给变量输出提供默认值,例如:

  1. <div><{$ceshi|default="默认"}></div> <!--没有定义变量时可以使用默认值 --><!--输出:默认-->

5.运算符

我们可以对模板输出使用运算符,包括对“+”“-” “*” “/”“++”“--”和“%”的支持。

  1. <{$a+$b*$c}><!--输出:110-->

在使用运算符的时候,不再支持点语法和常规的函数用法

6.模板继承

模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。

因此,模板继承的优势其实是设计基础模板中的区块(block)和子模板中替换这些区块。

每个区块由<block></block>标签组成。例如:

父模板:fu.html:

  1. <body>
  2. <block name="top">
  3. <div>这是头部信息</div>
  4. </block>
  5. <block name="content">
  6. <div>这是内容</div>
  7. </block>
  8. <block name="foot">
  9. <div>这是页脚</div>
  10. </block>

子模板:zi,html:

  1. <extend name="fu" /> <!-- 继承父模板 -->
  2. <!--将内容块变成自己的,与面向对象里面的继承一样,名字没有变,对父模板重写 -->
  3. <block name="content">
  4. <div style="width:100%; height:300px; background-color:#09F"></div>
  5. </block>
  6. <!--头部与尾部不变,可以做成父模板,子模板继承就可以了,减少代码量 -->

zi方法:

  1. function zi()
  2. {
  3. $this->display();
  4. }

7.三元运算符

  1. <div><{$pd?"男":"女"}></div><!--输出:男-->

三元运算符中暂时不支持点语法。

8.包含文件

在当前模版文件中包含其他的模版文件使用include标签,

模版表达式的定义规则为:模块@主题/控制器/操作

  1. <include file="Main/zi" /><!--引入模板文件-->

若从模块写会出错,所以不写模块了。

9.内置标签

  • IF标签
  1. <if condition="$a lt 10">
  2. <div>10</div>
  3. <elseif condition="$b gt 20 " />
  4. <div>20</div>
  5. <else />
  6. <div>30</div>
  7. </if>

注意条件的写法(condition双引号里面,不支持<,<=,>,>=,因为会混淆模板解析),else,elseif后面必须有 "/"

  • Foreach标签

name表示数据源, item表示循环变量,key表示索引。

可以输出索引,如下:

  1. <foreach name="shuzu" item="v">
  2. <div><{$key}> => <{$v}></div>
  3. </foreach>

也可以定义索引的变量名

  1. <foreach name="shuzu" item="v" key="k">
  2. <div><{$k}> => <{$v}></div>
  3. </foreach>
  • For标签
  1. <for start="开始值" end="结束值" comparison="" step="步进值" name="循环变量名" >
  2. </for>

开始值、结束值、步进值和循环变量都可以支持变量,开始值和结束值是必须,其他是可选。comparison 的默认值是lt;;name的默认值是i,步进值的默认值是1,举例如下:

  1. <for start="1" end="100">
  2.  <{$i}>
  3. </for>
  • Switch标签
  1. <switch name="变量" >
  2. <case value="值1" break="0或1">输出内容1</case> break默认自动添加
  3. <case value="值2">输出内容2</case>
  4. <default />默认情况
  5. </switch>
  • 标签嵌套

系统内置的标签中,volist、switch、if、elseif、else、foreach、compare(包括所有的比较标签)、(not)present、(not)empty、(not)defined等标签都可以嵌套使用。

  • import标签

传统方式的导入外部JS和CSS文件的方法是直接在模板文件使用:

这是根据src浏览调用的文件,此路径是根据当前模板文件找到的,但是不起作用,在浏览器中检查元素,此文件地址为:http://localhost/Public/Js/jisuan.js和http://localhost/Public/Css/abq.css。而去掉一个上级目录,变为

<script type="text/javascript" src="../../../Public/Js/jisuan.js"></script>
<link href="../../../Public/Css/abq.css" rel="stylesheet" type="text/css" />

此时检查元素文件地址变为:http://localhost/tp/Public/Js/jisuan.js和http://localhost/tp/Public/Css/abq.css。

此时可以起作用,虽然提示该文件不在本地磁盘上,但是这种方法很容易出错,不推荐。

TP框架提供了专门的标签来简化上面的导入:虽然可以使用文件,但是不会显示文件

第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:

<import type="js" file="JS/jisuan" />Type属性默认是js,所以js文件可以不用写type属性

<import type="css" file="CSS/abq" />

注意:将js、css文件放在Public文件夹下,若用src引入时会多写一个上级目录,切记一定要写对路径。

第二个是load标签,通过文件方式导入当前项目的公共JS或者CSS

<load href="/Public/JS/jisuan.js" />

<load href="/Public/CSS/abq.css" />这种写法有时不起作用,所以不推荐这样写。可以用下面这种方法:

在href属性中可以使用特殊模板标签替换,例如:

<load href="__PUBLIC__/Js/jisuan.js" />

Load标签可以无需指定type属性,系统会自动根据后缀自动判断。这种方法更简便,且不易出错,推荐使用。

系统还提供了两个标签别名js和css 用法和load一致,例如:

<js href="__PUBLIC__/JS/jisuan.js" />

<css href="__PUBLIC__/CSS/abq.css" />这种方法也很不错,推荐使用。

此时检查元素:

  • 原样输出

可以使用literal标签来防止模板标签被解析

  1. <literal>
  2. <if condition="$name eq 1 "> value1
  3. <elseif condition="$name eq 2"/>value2
  4. <else /> value3
  5. </if>
  6. </literal>

上面的if标签被literal标签包含,因此if标签里面的内容并不会被模板引擎解析,而是保持原样输出:

所有可能和内置模板引擎的解析规则冲突的地方都可以使用literal标签处理。

  • 模板注释

单行注释:<{/*注释内容*/}>或者<{//注释内容}>

多行注释:<{/*注释

      内容*/}>

  • 模板替换

在进行模板渲染之前,系统还会对读取的模板内容进行一些特殊字符串替换操作,也就是实现了模板输出的替换和过滤。该替换操作仅针对内置的模版引擎。

这个机制可以使得模板文件的定义更加方便,默认的替换规则有:

  1. __ROOT__: 会替换成当前网站的地址(不含域名)
  2. __APP__: 会替换成当前应用的URL地址 (不含域名)
  3. __MODULE__:会替换成当前模块的URL地址 (不含域名)
  4. __CONTROLLER__(__或者__URL__ 兼容考虑): 会替换成当前控制器的URL地址(不含域名)
  5. __ACTION__:会替换成当前操作的URL地址 (不含域名)
  6. __SELF__: 会替换成当前的页面URL
  7. __PUBLIC__:会被替换成当前网站的公共目录 通常是 /Public/

默认情况下,模板替换只会替换模板文件的特殊字符串,不会替换动态数据中的输出的内容。

注意这些特殊的字符串是严格区别大小写的,并且这些特殊字符串的替换规则是可以更改或者增加的,我们只需要在应用或者模块的配置文件中配置TMPL_PARSE_STRING就可以完成。

ThinkPHP框架基础知识二的更多相关文章

  1. ThinkPHP框架基础知识一

    ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来 ...

  2. ThinkPHP框架基础知识三

    一.JS文件与Css文件存放位置 其实JS与Css文件放在任意位置都可以找到,只要路径正确就行. 在TP框架中我们访问的所有文件都要走入口文件index.php,相当于访问的是index.php页面. ...

  3. PHP面试(二):程序设计、框架基础知识、算法与数据结构、高并发解决方案类

    一.程序设计 1.设计功能系统——数据表设计.数据表创建语句.连接数据库的方式.编码能力 二.框架基础知识 1.MVC框架基本原理——原理.常见框架.单一入口的工作原理.模板引擎的理解 2.常见框架的 ...

  4. Hive框架基础(二)

    * Hive框架基础(二) 我们继续讨论hive框架 * Hive的外部表与内部表 内部表:hive默认创建的是内部表 例如: create table table001 (name string , ...

  5. HBase框架基础(二)

    * HBase框架基础(二) 上一节我们了解了HBase的架构原理和模块组成,这一节我们先来聊一聊HBase的读写数据的过程. * HBase的读写流程及3个机制 HBase的读数据流程: 1.HRe ...

  6. DDD框架基础知识

    DDD框架基础知识 参考: https://www.cnblogs.com/zhili/p/OnlineStorewithDDD.html(领域驱动设计,分层架构) https://www.cnblo ...

  7. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  8. java 基础知识二 基本类型与运算符

    java  基础知识二 基本类型与运算符 1.标识符 定义:为类.方法.变量起的名称 由大小写字母.数字.下划线(_)和美元符号($)组成,同时不能以数字开头 2.关键字 java语言保留特殊含义或者 ...

  9. 菜鸟脱壳之脱壳的基础知识(二) ——DUMP的原理

    菜鸟脱壳之脱壳的基础知识(二)——DUMP的原理当外壳的执行完毕后,会跳到原来的程序的入口点,即Entry Point,也可以称作OEP!当一般加密强度不是很大的壳,会在壳的末尾有一个大的跨段,跳向O ...

随机推荐

  1. storm 入门原理介绍_AboutYUN

    转自:http://www.aboutyun.com/thread-7394-1-1.html 了解Storm:http://www.aboutyun.com/thread-9547-1-2.html ...

  2. 在一个千万级的数据库查寻中,如何提高查询效率?分别说出在数据库设计、SQL语句、java等层面的解决方案。

    在一个千万级的数据库查寻中,如何提高查询效率?分别说出在数据库设计.SQL语句.java等层面的解决方案. 解答: 1)数据库设计方面: a. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 whe ...

  3. <!>表格语法

    <table aling=left>...</table>表格位置,置左 <table aling=center>...</table>表格位置,置中 ...

  4. 嵌入式开发之信号采集同步---VSYNC和HSYNC的作用以及它们两者之间的关系

    VSYNC和HSYNC的作用以及它们两者之间的关系 VSYNC和HSYNC的作用以及它们两者之间的关系 VSYNC和HSYNC是什么 VSYNC: vertical synchronization,指 ...

  5. .NET中的枚举用法浅析

    本文简单分析了.NET中的枚举用法.分享给大家供大家参考.具体分析如下: 我理解的枚举就是编程中约定的一个“可选值”:例如QQ的在线状态,分别有    在线,Q我吧,隐身,忙碌等等...我觉得这就是一 ...

  6. Multiview

    新建3个ViewController的类 新建main.stroyboard,并配置好相应的布局(编辑界面,连接视图与类,ViewController的Storyboard ID,连接3个Button ...

  7. hiho一下第107周《Give My Text Back》

    题目链接:传送门 题目大意:给你多组格式不标准的字符串句子,要你恢复到标准格式(单词中间只有一个空格或者一个逗号一个空格,句子的首字母大写其他小写,遇到回车也要换行) 题目思路:直接按题意模拟,注意几 ...

  8. [转]python-元类

    转载于:刘羽冲 两句话掌握python最难知识点——元类 千万不要被所谓“元类是99%的python程序员不会用到的特性”这类的说辞吓住.因为每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两 ...

  9. MySQL安装和Navicat安装、破解

    1)mysql下载 地址:https://dev.mysql.com/downloads/mysql/ 2)一路next安装,安装好后文件目录如下(不包括data文件夹,my.ini文件) 3)新建文 ...

  10. Powershell About Active Directory Server

    一.获取域控制器服务器清单 (Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ } | select hos ...