[php] TP常用
获取变量
可以在开发过程中使用传统方式获取各种系统变量,例如:
$id = $_GET['id']; // 获取get变量
$name = $_POST['name']; // 获取post变量
$value = $_SESSION['var']; // 获取session变量
$name = $_COOKIE['name']; // 获取cookie变量
$file = $_SERVER['PHP_SELF']; // 获取server变量
TP不建议直接使用传统方式获取,因为没有统一的安全处理机制,后期如果调整的话,改起来会比较麻烦。所以,更好的方式是在框架中统一使用I函数进行变量获取和过滤。
#I方法
I('变量类型.变量名',['默认值'],['过滤方法'],['额外数据源'])
变量类型是指请求方式或者输入类型,包括:
#变量类型 含义
get 获取GET参数
post 获取POST参数
param 自动判断请求类型获取GET、POST或者PUT参数
request 获取REQUEST 参数
put 获取PUT 参数
session 获取 $_SESSION 参数
cookie 获取 $_COOKIE 参数
server 获取 $_SERVER 参数
globals 获取 $GLOBALS参数
path 获取 PATHINFO模式的URL参数(3.2.2新增)
data 获取 其他类型的参数,需要配合额外数据源参数(3.2.2新增)
注意:变量类型不区分大小写。
变量名则严格区分大小写。
默认值和过滤方法均属于可选参数。
以GET变量类型为例,说明下I方法的使用:
echo I('get.id'); // 相当于 $_GET['id']
echo I('get.name'); // 相当于 $_GET['name']
支持默认值:
echo I('get.id',0); // 如果不存在$_GET['id'] 则返回0
echo I('get.name',''); // 如果不存在$_GET['name'] 则返回空字符串
采用方法过滤:
// 采用htmlspecialchars方法对
$_GET['name'] 进行过滤,如果不存在则返回空字符串echo I('get.name','','htmlspecialchars');
支持直接获取整个变量类型,例如:
// 获取整个$_GET 数组
I('get.');
用同样的方式,我们可以获取post或者其他输入类型的变量,例如:
I('post.name','','htmlspecialchars');
// 采用htmlspecialchars方法对$_POST['name']进行过滤,如果不存在则返回空字符串
I('session.user_id',0); // 获取$_SESSION['user_id'] 如果不存在则默认为0
I('cookie.'); // 获取整个 $_COOKIE 数组
I('server.REQUEST_METHOD'); // 获取 $_SERVER['REQUEST_METHOD']
param变量类型是框架特有的支持自动判断当前请求类型的变量获取方式,例如:
echo I('param.id');
如果当前请求类型是GET,那么等效于 $_GET['id'],如果当前请求类型是POST或者PUT,那么相当于获取 $_POST['id'] 或者 PUT参数id。
由于param类型是I函数默认获取的变量类型,因此事实上param变量类型的写法可以简化为:
I('id'); // 等同于 I('param.id')
I('name'); // 等同于 I('param.name')
3.2.2新增了path和data两个变量类型,用法如下:
path类型变量可以用于获取URL参数(必须是PATHINFO模式参数有效,无论是GET还是POST方式都有效),例如:当前访问URL地址是 http://serverName/index.php/New/2013/06/01
那么我们可以通过
echo I('path.1'); // 输出2013
echo I('path.2'); // 输出06
echo I('path.3'); // 输出01
data类型变量可以用于获取不支持的变量类型的读取,例如:
I('data.file1','','',$_FILES);
#变量过滤
如果没有在调用I函数的时候指定过滤方法的话,系统会采用默认的过滤机制(由DEFAULT_FILTER配置),事实上,
该参数的默认设置是:
// 系统默认的变量过滤机制
'DEFAULT_FILTER' => 'htmlspecialchars'
也就说,I方法的所有获取变量如果没有设置过滤方法的话都会进行htmlspecialchars过滤,那么:
// 等同于 htmlspecialchars($_GET['name'])
I('get.name');
同样,该参数也可以设置支持多个过滤,例如:
'DEFAULT_FILTER' => 'strip_tags,htmlspecialchars'
设置后,再使用:
// 等同于 htmlspecialchars(strip_tags($_GET['name']))
I('get.name');
如果再使用I方法的时候 指定了过滤方法,那么就会忽略DEFAULT_FILTER的设置,例如:
// 等同于 strip_tags($_GET['name'])
echo I('get.name','','strip_tags'); I方法的第三个参数如果传入函数名,则表示调用该函数对变量进行过滤并返回(在变量是数组的情况下自动使用array_map进行过滤处理),否则会调用PHP内置的filter_var方法进行过滤处理,例如:
I('post.email','',FILTER_VALIDATE_EMAIL);
表示 会对$_POST['email'] 进行 格式验证,如果不符合要求的话,返回空字符串。
或者可以用下面的字符标识方式:
I('post.email','','email');
// 下面两种方式都不采用任何过滤方法
I('get.name','','');
I('get.id','',false);
一旦过滤参数设置为空字符串或者false,即表示不再进行任何的过滤。
URL生成
U方法
U('地址表达式',['参数'],['伪静态后缀'],['显示域名'])
定义规则
#地址表达式
地址表达式的格式定义如下:
[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...
如果不定义模块的话 就表示当前模块名称,下面是一些简单的例子:
U('User/add') // 生成User控制器的add操作的URL地址
U('Blog/read?id=1') // 生成Blog控制器的read操作 并且id为1的URL地址
U('Admin/User/select') // 生成Admin模块的User控制器的select操作的URL地址
#参数
U方法的第二个参数支持数组和字符串两种定义方式,如果只是字符串方式的参数可以在第一个参数中定义,例如:
U('Blog/cate',array('cate_id'=>1,'status'=>1))
U('Blog/cate','cate_id=1&status=1')
U('Blog/cate?cate_id=1&status=1')
三种方式是等效的,都是生成Blog控制器的cate操作 并且cate_id为1 status为1的URL地址。
但是不允许使用下面的定义方式来传参数
U('Blog/cate/cate_id/1/status/1');
#伪静态后缀
U函数会自动识别当前配置的伪静态后缀,如果你需要指定后缀生成URL地址的话,可以显式传入,例如:
U('Blog/cate','cate_id=1&status=1','xml');
#自动识别
根据项目的不同URL设置,同样的U方法调用可以智能地对应产生不同的URL地址效果,例如针对:
U('Blog/read?id=1');这个定义为例。
如果当前URL设置为普通模式的话,最后生成的URL地址是:
http://serverName/index.php?m=Blog&a=read&id=1
如果当前URL设置为PATHINFO模式的话,同样的方法最后生成的URL地址是:
http://serverName/index.php/Home/Blog/read/id/1
如果当前URL设置为REWRITE模式的话,同样的方法最后生成的URL地址是:
http://serverName/Home/Blog/read/id/1
如果当前URL设置为REWRITE模式,并且设置了伪静态后缀为.html的话,同样的方法最后生成的URL地址是:
http://serverName/Home/Blog/read/id/1.html
如果开启了URL_CASE_INSENSITIVE,则会统一生成小写的URL地址。
#生成路由地址
U方法还可以支持路由,如果我们定义了一个路由规则为:
'news/:id\d'=>'News/read'那么可以使用
U('/news/1');最终生成的URL地址是:
http://serverName/index.php/Home/news/1
注意:如果是在模板文件中直接使用U方法的话,需要采用 {:U('参数1', '参数2'…)} 的方式
#域名支持
如果涉及到多个子域名的操作地址,那么也可以在U方法里面指定需要生成地址的域名,例如:
U('Blog/read@blog.thinkphp.cn','id=1');
@后面传入需要指定的域名即可。
系统会自动判断当前是否SSL协议,生成https://
此外,U方法的第4个参数如果设置为true,表示自动识别当前的域名,并且会自动根据子域名部署设置APP_SUB_DOMAIN_DEPLOY和APP_SUB_DOMAIN_RULES自动匹配生成当前地址的子域名。
#锚点支持
U函数可以直接生成URL地址中的锚点,例如:
U('Blog/read#comment?id=1');
生成的URL地址可能是:
http://serverName/index.php/Home/Blog/read/id/1#comment
volist
通常模型的select方法返回的结果是一个二维数组,可以直接使用volist标签进行输出。在控制器中首先对模版赋值:
$User = M('User');
$list = $User->limit(10)->select();
$this->assign('list',$list);
在模版定义如下,循环输出用户的编号和姓名:
<volist name="list" id="vo">
{$vo.id}:{$vo.name}<br/>
</volist>
Volist标签的name属性表示模板赋值的变量名称,因此不可随意在模板文件中改变。id表示当前的循环变量,可以随意指定,但确保不要和name属性冲突,例如:
<volist name="list" id="data">
{$data.id}:{$data.name}<br/>
</volist>
支持输出查询结果中的部分数据,例如输出其中的第5~15条记录
<volist name="list" id="vo" offset="5" length='10'>
{$vo.name}
</volist>
输出偶数记录
<volist name="list" id="vo" mod="2" >
<eq name="mod" value="1">{$vo.name}</eq>
</volist>
Mod属性还用于控制一定记录的换行,例如:
<volist name="list" id="vo" mod="5" >
{$vo.name}<eq name="mod" value="4"><br/></eq>
</volist>
为空的时候输出提示:
<volist name="list" id="vo" empty="暂时没有数据" >
{$vo.id}|{$vo.name}
</volist>
empty属性不支持直接传入html语法,但可以支持变量输出,例如:
$this->assign('empty','<span class="empty">没有数据</span>');$this->assign('list',$list);然后在模板中使用:
<volist name="list" id="vo" empty="$empty" >
{$vo.id}|{$vo.name}
</volist>
输出循环变量
<volist name="list" id="vo" key="k" >
{$k}.{$vo.name}
</volist>
如果没有指定key属性的话,默认使用循环变量i,例如:
<volist name="list" id="vo" >
{$i}.{$vo.name}
</volist>
如果要输出数组的索引,可以直接使用key变量,和循环变量不同的是,这个key是由数据本身决定,而不是循环控制的,例如:
<volist name="list" id="vo" >
{$key}.{$vo.name}
</volist>
模板中可以直接使用函数设定数据集,而不需要在控制器中给模板变量赋值传入数据集变量,如:
<volist name=":fun('arg')" id="vo">
{$vo.name}
</volist>
IF
<if condition="($name eq 1) OR ($name gt 100) ">
value1
<elseif condition="$name eq 2"/>
value2
<else />
value3
</if>
在condition属性中可以支持eq等判断表达式,同上面的比较标签,但是不支持带有”>”、”<”等符号的用法,因为会混淆模板解析,
所以下面的用法是错误的:
<if condition="$id < 5 ">
value1
<else />
value2
</if>
必须改成:
<if condition="$id lt 5 ">
value1
<else />
value2
</if>
除此之外,可以在condition属性里面使用php代码,例如:
<if condition="strtoupper($user['name']) neq 'THINKPHP'">
ThinkPHP
<else />
other Framework
</if>
condition属性可以支持点语法和对象语法,例如:自动判断user变量是数组还是对象
<if condition="$user.name neq 'ThinkPHP'">
ThinkPHP
<else />
other Framework
</if>
或者知道user变量是对象
<if condition="$user:name neq 'ThinkPHP'">
ThinkPHP
<else />
other Framework
</if>
由于if标签的condition属性里面基本上使用的是php语法,尽可能使用判断标签和Switch标签会更加简洁,原则上来说,能够用switch和比较标签解决的尽量不用if标签完成。因为switch和比较标签可以使用变量调节器和系统变量。如果某些特殊的要求下面,IF标签仍然无法满足要求的话,可以使用原生php代码或者PHP标签来直接书写代码。
比较标签
比较标签用于简单的变量比较,复杂的判断条件可以用if标签替换,比较标签是一组标签的集合,基本上用法都一致
<比较标签 name="变量" value="值">
内容
</比较标签>
系统支持的比较标签以及所表示的含义分别是:
标签 含义
eq或者equal 等于
neq 或者notequal 不等于
gt 大于
egt 大于等于
lt 小于
elt 小于等于
heq 恒等于
nheq 不恒等于
他们的用法基本是一致的,区别在于判断的条件不同,并且所有的比较标签都可以和else标签一起使用。
例如,要求name变量的值等于value就输出,可以使用:
<eq name="name" value="value">
value
</eq>
或者
<equal name="name" value="value">
value
</equal>
也可以支持和else标签混合使用:
<eq name="name" value="value">
相等
<else/>
不相等
</eq>
当 name变量的值大于5就输出
<gt name="name" value="5">
value
</gt>
当name变量的值不小于5就输出
<egt name="name" value="5">
value
</egt>
比较标签中的变量可以支持对象的属性或者数组,甚至可以是系统变量,例如:
当vo对象的属性(或者数组,或者自动判断)等于5就输出
<eq name="vo.name" value="5">
{$vo.name}
</eq>
当vo对象的属性等于5就输出
<eq name="vo:name" value="5">
{$vo.name}
</eq>
当$vo['name']等于5就输出
<eq name="vo['name']" value="5">
{$vo.name}
</eq>
而且还可以支持对变量使用函数 当vo对象的属性值的字符串长度等于5就输出
<eq name="vo:name|strlen" value="5">
{$vo.name}
</eq>
变量名可以支持系统变量的方式,例如:
<eq name="Think.get.name" value="value">
相等
<else/>
不相等
</eq>
通常比较标签的值是一个字符串或者数字,如果需要使用变量,只需要在前面添加“$”标志:当vo对象的属性等于$a就输出
<eq name="vo:name" value="$a">
{$vo.name}
</eq>
所有的比较标签可以统一使用compare标签(其实所有的比较标签都是compare标签的别名),例如:
当name变量的值等于5就输出
<compare name="name" value="5" type="eq">
value
</compare>等效于
<eq name="name" value="5" >
value
</eq>
其中type属性的值就是上面列出的比较标签名称
Switch
<switch name="变量" >
<case value="值1" break="0或1">
输出内容1
</case>
<case value="值2">
输出内容2
</case>
<default />
默认情况
</switch>
使用方法如下:
<switch name="User.level">
<case value="1">
value1
</case>
<case value="2">
value2
</case>
<default />
default
</switch>
其中name属性可以使用函数以及系统变量,例如:
<switch name="Think.get.userId|abs">
<case value="1">
admin
</case>
<default />
default
</switch>
对于case的value属性可以支持多个条件的判断,使用”|”进行分割,例如:
<switch name="Think.get.type">
<case value="gif|png|jpg">
图像格式
</case>
<default />
其他格式
</switch>
表示如果$_GET["type"] 是gif、png或者jpg的话,就判断为图像格式。
Case标签还有一个break属性,表示是否需要break,默认是会自动添加break,如果不要break,可以使用:
<switch name="Think.get.userId|abs">
<case value="1" break="0">
admin
</case>
<case value="2">
admin
</case>
<default />
default
</switch>
也可以对case的value属性使用变量,例如:
<switch name="User.userId">
<case value="$adminId">
admin
</case>
<case value="$memberId">
member
</case>
<default />
default
</switch>
使用变量方式的情况下,不再支持多个条件的同时判断。
empty
empty标签用于判断某个变量是否为空,用法:
<empty name="name">
name为空值
</empty>
如果判断没有赋值,可以使用:
<notempty name="name">
name不为空
</notempty>
可以把上面两个标签合并成为:
<empty name="name">
name为空
<else />
name不为空
</empty>
name属性可以直接使用系统变量,例如:
<empty name="Think.get.name">
$_GET['name']为空值
</empty>