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

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

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”,这个控制器的空操作都会自动执行该方法。(推荐使用)不要在父类中建,要在子类中建。

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

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

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

<body>
<h1>别乱访问!</h1>
</body>

这样在访问该空操作时:

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

2、空控制器

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

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

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

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

<?php
namespace Home\Controller;
use Think\Controller;
class EmptyController extends Controller
{
function _empty()
{
echo "<h1>访问的页面不存在!</h1>";
}
}

这样再次请求:

二、跨控制器调用方法

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

Index控制器:

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller { public function ShuChu()
{
return "教务管理系统";
}
}

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

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

Main控制器:

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

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

三、跨模块调用

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

<?php
namespace Admin\Controller;
use Think\Controller;
class TestController extends Controller
{
public function Test()
{ return "Admin模块操作";
}
}

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

<?php
namespace Home\Controller;
use Think\Controller;
class MainController extends Controller
{
function ShuChu()
{
//跨模块调用方法
//使用A方法
$test = A("Admin/Test");
echo $test->Test(); //使用R方法
echo R("Admin/Test/Test");
}
}

这样访问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注册变量,然后在模板中使用<{ }>来标记使用变量

function Test()
{
//注册变量
$this->assign("a",10);
$this->assign("b",20);
     $this->assign("pd",true);
$this->assign("test","hello");
$attr = array("one"=>100,"two"=>200,"three"=>300);
$this->assign("shuzu",$attr);
$this->display();
}

在Test.html中:

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

输出:

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

2.系统变量

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

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

还可以输出常量:

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

输出:

输出配置参数使用:

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

输出:

3.使用函数

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

<{$data.name|md5} >

4.默认值输出

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

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

5.运算符

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

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

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

6.模板继承

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

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

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

父模板:fu.html:

<body>
<block name="top">
<div>这是头部信息</div>
</block>
<block name="content">
<div>这是内容</div>
</block>
<block name="foot">
<div>这是页脚</div>
</block>

子模板:zi,html:

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

zi方法:

function zi()
{
$this->display();
}

7.三元运算符

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

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

8.包含文件

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

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

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

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

9.内置标签

  • IF标签
<if condition="$a lt 10">
<div>10</div>
<elseif condition="$b gt 20 " />
<div>20</div>
<else />
<div>30</div>
</if>

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

  • Foreach标签

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

可以输出索引,如下:

<foreach name="shuzu" item="v">
<div><{$key}> => <{$v}></div>
</foreach>

也可以定义索引的变量名

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

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

<for start="1" end="100">
 <{$i}>
</for>
  • Switch标签
<switch name="变量" >
<case value="值1" break="0或1">输出内容1</case> break默认自动添加
<case value="值2">输出内容2</case>
<default />默认情况
</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标签来防止模板标签被解析

<literal>
<if condition="$name eq 1 "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>
</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. mean 快速开发和现有技术的对比分析

    最近无聊的时候,网上看了下全栈开发的相关资料,发现了mean这个好玩的东西.可能我是一个比较传统的开发,接触.net 已经将近快8年了,一直在传统的后端多层架构的模式下开发,一时对这个新的东西就喜欢研 ...

  2. Tensorflow之计算tensor平均值

    https://www.tensorflow.org/versions/r0.12/api_docs/python/math_ops.html#reduce_mean tf.reduce_mean(i ...

  3. 【vijos】1746 小D的旅行(dijkstra)

    https://vijos.org/p/1746 这题就是水题.裸的跑完每个点的最短路后直接可以暴力出解.. 这题贴出来是因为我改了下我的dijkstra的模板...(其实是原来一直写错了233 注意 ...

  4. The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha

    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha ...

  5. linux less使用方法

    less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...

  6. PrintArea打印,@media screen解决移动web开发的多分辨率问题,@media print设置打印的样式

    PrintArea打印,局部DIV打印插件,依赖JQuery. github:https://github.com/RitsC/PrintArea 当打印时需要临时改变页面布局,可以使用 @media ...

  7. PAXOS: libevent_paxos

    PAXOS实现 -- libevent_paxos 该文章是项目的一部分.主要讲PAXOS算法的实现.                                                  ...

  8. iOS-数组,字典常用的字面量写法

    解决方法: //用字面量创建数组 NSArray *array = @[@"one",@"two"]; //用字面量创建字典 NSDictionary *dic ...

  9. 不固定宽度的div居中显示

    对于div的居中 ,如果是有固定宽高的,可以加margin:auto;水平垂直居中,但如果是不固定宽高,又想让div居中的话,这种方式都可能不奏效,达不到想要的效果. 有两种方法:1.加display ...

  10. FineReport---样式

    1.单元格样式 单元格样式说明 2.预定义样式 预定义样式说明 这里发现,改了样式,服务器更新Congfig,需要重启服务器,这样比较麻烦 我的操作是,先设置预定义样式,然后再点击自定义样式,操作是就 ...