ThinkPHP

-配置文件

如果需要在项目文件自定义一个配置文件如user.php,则需要在当前项目config.php中加载
自定义的配置文件会在每次运行的时候都加载一遍,而config只加载一次就存到编译模板里了,所以尽量不要用自定义配置文件

user.php
<?php
    return array(
     'name'=>'ding'
    );
?>

config.php
<?php
    return array(
     'LOAD_EXT_CONFIG'=>'user'
    );
?>

C方法

用于获取输出配置文件信息

echo C("URL_MODEL");

用于动态设置配置参数的值

C("URL_MODEL","0");

用于获取二维数组配置参数的值,和动态设置

C("USER_CONFIG.USER_TYPE","0");

批量动态设置配置参数的值

$config = array("URL_MODEL"=>"1","USER_NAME"=>"ac");
C($config);

U方法

生成一个url地址
U('地址表达式',['参数'],['伪静态后缀'],['显示域名'])
U(‘控制器/方法’,array("id"=>"1"),''html","localhost")

echo U('Index/index',array("id"=>"1"))//生成Thinkphp_imooc/index.php/Home/Index/index/id/1
echo U('Index/index','id=1&name=2')

这里伪静态后缀,会把后缀当做一个参数,而不是连接的网址

echo $_GET['id']//输出1.sshtml;
需要配合
'URL_HTML_SUFFIX'=>'sshtml|html' //“|”代表多个参数
才能当做网址执行而不是参数

-自定义函数

自定义函数需要定义在项目目录的common目录里,并且起名为function.php

-模板赋值

      三种方法
//这种方法支持连续赋值
$this->assign('name','Victor')->assign('sex','男')->assign('day','23');
//还有一种方法
$this->name = "victor";
//数组赋值
$arr = array('name'=>'Victor','sex'=>"男",'year'=>'2017');
$this->assign($arr);

-模板变量输出与运算

如果是一个me数组
{$me['name']}
{$me.sex}
{$me.boy|default=50}//默认输出

+—*/运算
{$me['num']+1}

-模板函数调用

{$me['name']|md5|substr=0,5}//先加密,再截取,相当于substr(md5($me['name']),0,5)
{$time|date='Y-m-d H:i:s',###}//把时间戳格式化
常量
{$Think.now}//当前时间
<br/>
{$Think.ersion}//当前框架的版本

-volist和foreach标签

$person = array(
    1=>array('name'=>'Jack','age'=>'18'),
    2=>array('name'=>'Tom','age'=>'19'),
    3=>array('name'=>'Peter','age'=>'20'),
    4=>array('name'=>'Mary','age'=>'21'),
);
$this->assign('person',$person);

tpl.php
//volist可以灵活的使用
<volist name="person" id="data">
    {$data['name']}------{$data['age']}<br/>
</volist>
//输出数据,从第二个开始,输出两个
<volist name="person" id="data" offset="2" length="2">
    {$data['name']}------{$data['age']}<br/>
</volist>
//输出偶数记录
<volist name="person" id="data" mod="2">
    <eq name="mod" value="1">{$data['name']}------{$data['age']}</eq><br/>
</volist>
//为空的时候输出提示信息
<volist name="person" id="data" empty="我没有数据">
    {$data['name']}------{$data['age']}<br/>
</volist>

//foreach标签
<foreach name="person" item="val">
    {$val.name}:
    {$val.age}<br/>
</foreach>

-标识号


eq =,neq !=,gt >,lt <.egt >=,elt <=,heq ===,nheq!===

-for标签

<for start="开始至" end="结束值" comparison="" step="步进值" name="循环变量名">
</for>

开始值、结束值、步进值和循环变量都可以支持变量,开始值和结束值是必须,其他是可选。 comparison 的默认值是lt;;name的默认值是i,步进值的默认值是1
<for start="1" end="10" name="k">
    {$k}<br/>
</for>

-IF()判断

//只有一个参数confition="",此参数支持php原生语法,对象
<if condition="$num gt 10">
num 大于 10
    <elseif condition="$num lt 10"/>//后边结束符千万不要忘记
    num 小于 10
    <else/>
        num等于10
</if>
//php语法
<if condition="strtoupper($user['name']) neq 'THINKPHP'">ThinkPHP
<else /> other Framework
</if>

-switch()判断

其中name属性可以使用函数以及系统变量,
也可以对case的value属性使用变量
Case标签还有一个break属性,表示是否需要break,默认是会自动添加break,如果不要break,可以break=0;
$name = "laoshi";
$this->assign('name',$name);

tpl
<switch name="name">
    <case value="laoshi">小明滚出去</case>
    <case value="xiaohong">小明,你滚出去</case>
    <case value="xiaozhu|xiaogou">你们都滚出去</case>//多条件判断
    <default/>小明,自己滚出去
</switch>

-比较标签

<!--<比较标签 name="变量名" value="比较的值"></比较标签>-->
<eq name="name" value="10">num=10</eq>
//所有的比较标签都支持else
<eq name="name" value="10">num=10<else/>num不等于10</eq>

所有的比较标签可以统一使用compare标签(其实所有的比较标签都是compare标签的别名),例如:
<compare name="name" value="10" type="eq">name=10<else/>name!=10</compare>

-范围判断标签

范围判断标签包括in notin between notbetween四个标签,都用于判断变量是否中某个范围。
//IN
<in name="name" value="1,2,3">在这个区间<else/>不在</in>
//NOTIN
<notin name="name" value="1,2,3">不在这个区间</notin>
//BETWEEN
<between name="name" value="1,10">在1-10区间</between>
//NOTBETWEEN
<notbetween name="name" value="1,10">不在1-10区间</notbetween>

也可以直接使用range标签,替换前面的判断用法:
<range name="name" value="1,11,12" type="in">有11这个数<else/>没有</range>

-模板的三元运算符

{$name>11?"大于11":"不大于11"}

-模板原生PHP代码

<php>ehco $name;<php>

-调试模式

调试模式的优势在于: 开启日志记录,任何错误信息和调试信息都会详细记录,便于调试;
关闭模板缓存,模板修改可以即时生效;
记录SQL日志,方便分析SQL; 关闭字段缓存,数据表字段修改不受缓存影响;
严格检查文件大小写(即使是Windows平台),帮助你提前发现Linux部署可能导致的隐患问题;

在开启调试模式的状态下,系统会首先导入框架默认的调试模式配置文件,该文件位于系统目录 的 Conf\debug.php 。
通常情况下,调试配置文件里面可以进行一些开发模式所需要的配置。 例如,配置额外的数据库连接用于调试,开启日志写入便于查找错误信息、开启页面Trace输出更多的调试信息等等。
如果检测到应用的配置目录中有存在debug.php文件,则会自动加载该配置文件,并且和系统项目配置文件以及系统调试配置文件合并,也就是说,debug.php配置文件只需要配置和项目配置文件以及系统 调试配置文件不同的参数或者新增的参数。

通过页面Trace功能更好的调试和发现错误;

在debug.php中
'SHOW_PAGE_TRACE'=>true,//显示页面trace信息

trace('name',C('name'));//在trace显示变量信息

dump($_SERVER);//相当于var_dump,但更友好

-性能调试 G()函数

G('begin');
for($i=0;$i<10000;$i++){
    $count += $i;
}
G('end');

echo G('run','end');//返回这段代码执行耗时、秒
默认的统计精度是小数点后4位,如果觉得这个统计精度不够,还可以设置例如:
echo G('run','end',6);
如果你的环境支持内存占用统计的话,还可以使用G方法进行区间内存开销统计(单位为kb),例如:
echo G('run','end',m);
同样,如果end标签没有被标记的话,会自动把当前位置先标记位end标签。

-错误调试 E()函数

//输出错误信息,并中止执行
E($msg);

-数据库连接,主从服务器分离

return array(
   //'配置项'=>'配置值'
    'DB_TYPE'=>'mysql',//数据类型
    'DB_HOST'=>'localhost,localhost1,localhost2',//数据服务器地址
    'DB_NAME'=>'muke',//数据库名
    'DB_USER'=>'root',//数据库用户密码
    'DB_PWD'=>'root',//数据库密码
    'DB_PORT'=>'3306',//数据库端口
    //'DB_PREFIX'=>'',//数据表前缀
    //开启主从读写分离
    'DB_RW_SEPARATE'=>true,
    //多个主数据服务器
    'DB_MASTER_UNM'=>'2',
);
其中localhost, localhost 1是主服务器,localhost2是从服务器

-插入多条数据到数据库

$user = new Model('user');//表明,表前缀,数据库连接信息
for($i=1;$i<=100;$i++){
    $user->execute("insert into `mk_user` VALUES ('$i','hello$i','我是$i','asdfgh$i','$date','$date')");
}

-实例化模型

M() M方法实例化基础模型,参数可以填表明,也可以不写

D() D方法可以在参数里的模型不存在时自动执行M方法实例化基础模型

public function user(){
        //1.实例化基础模型 model
            //$user = new Model('user');//表明,表前缀,数据库连接信息
//            $user = M('user');
//            $data = $user->select();
            // dump($data);
        //2.实例化用户自定义模型
            //$user = new UserModel();
            $user = D('User');//D方法可以在User模型不存在时自动执行M方法实例化基础模型
            //echo $user->getinfo();
            $data = $user->select();
            dump($data);

        定义ConmonModel.class.php
        <?php
            namespace Home\Model;
            use Think\Model;
            class CommonModel extends Model{
            public function strmake($str){
                return md5(sha1(md5($str)));
                }
            }
         //3.实例化公共模型
         //$user = new CommonModel();
         //echo $user->strmake('aaaaa');
     可以把3和2合并到一起,直接把2的类改为继承CommonModel就行,因为Commondel已经继承公共模型Model了
         直接实例化 $user = D('User');
                echo $user->strmake('aaaaa');

    //4.实例化空模型
        $model = M();

        $data = $model->query('select * from mk_user');//读取 日常 select
        dump($data);
        //$model->execute($sql);//写入 update insert

命名空间

namespace Home\Controller;
          use Think\Controller;

URL访问模式配置

默认的是PATHINFO模式,如果要改需要在配置文件里定义“URL_MODEL”=>"0"

普通模式 ,0, http://localhost/index.php?m=home&c=user&a=login

PATHINFO模式 ,1, http://localhost/index.php/home/user/login

REWRITE模式 ,2, http://localhost/home/user/login

兼容模式 ,3, http://localhost/index.php?s=/home/user/login

注意REWRITE模式需要在apache配置文件开启rewrite.so
而且要在项目里index.php同级目录里建一个.htaccess文件,文件内容如下

<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

跳转和重定向

操作成功或者操作错误页面,并且自动跳转到另一个目标页面。系统的\Think\Controller类内置了这两个跳转方法success()和error(),这两个方法都有三个参数。第一个表示提示信息,第二个跳转地址,第三个表示跳转时间(秒)

if($res=='success'){
     $this->success('操作成功',U('Index/index'),5);
}else{
     $this->error('操作失败');
}

跳转地址是可选的,success方法的默认地址是$_SEVER("HTTP_REFERER"),而error模式是javascript:history.back(-1);上一个页面

重定向

$this->redirect('User/index',array('id'=>1),5,'页面跳转中。。。');只有第一个参数必选

如果仅仅想重定向到制定url,而不是某个模块的操作方法,可以直接使用redirect

redirect('/User/index/id/1',5,'页面跳转中。。。');

空操作

空操作是指系统在找不到请求的操作方法中,会定位到空操作_empty方法来执行,利用这个机制,可以对不存在的操作统一处理,空操作必须继承Think\Controller才能实现

class EmptyActionController extends Controller{
     public function _empty(){
          echo 不存在的操作;
     }
}

空控制器

定义一个EmptyController控制器文件来处理不存在的控制器,与上类似

跨控制器调用:即在一个控制器中调用另一个控制器的方法

(1)直接实例化

$goods = new GoodsController();
$info = $goods->info();
如果实例化的控制器与当前控制器不在同一目录,需要指定绝对路径
$goods = new \Admin\Controller\UserController();

(2) A函数直接实例化

$goods=A('Goods');
//实例其他模块下的控制器
$goods=A('Admin/Goods')

(3) R函数直接实例化

R与A不同的是R可以在实例化时连操作方法一起传过去
$info = R('Admin/Goods/info');

-模型

实例化模型类
  D()方法如果带参数会与参数同名的数据表相关联
  D()方法和M()方法用法一样,所不同的是M方法不论是否有方法实例的都是基础模型类\Think\Model
 实例化空模型类
$model=M();
$info=$model->query('show databases');
      直接实例化
$Goods = new \Home\Model\GoodsModel();

如果自定义了一个类,并且自定义了方法,M方法将无法调用这个操作,实例化时会自动忽略该操作,如果用D方法实例化则可以

模型的CRUD操作

数据查询where

//1.直接使用字符串进行查找
$data = M('user')->where('id=1')->select();//生成语句 select * from user where id=1;
//2.使用数组方式进行查询
$where['id'] = 2;
$where['user_name'] = 'xiaoming';
$data = M('user')->where($where)->select(); //生成语句 select * from user where id=2 and user_name='xiaoming';
dump($data);
如果进行多字段查询,那么字段之间的默认逻辑关系是 逻辑与 AND,但是用下面的规则可以更改默认的 逻辑判断,通过使用 _logic 定义查询逻辑:
$where['id'] = 2;
$where['user_name'] = 'xiaoming';
$where['_logic'] = 'or';
$data = M('user')->where($where)->select(); //生成语句 select * from user where id=2 OR user_name='xiaoming';

表达式查询 eq neq gt egt lt elt like between in exp notbetween notin

$where['字段名] = array(表达式,查询条件);
$where['id'] = array('lt',3);//查询id小于3
$data = M('user')->where($where)->select();

//between查询id为1-8
$where['id'] = array('between','1,8');
//in between查询1和2
$where['id'] = array('in','1,2');
//like 模糊查询
$where['user_name'] = array('like','%ming');
$where['user_name'] = array('like',array('%ming','xiao%'));//多个like查询 SELECT * FROM `mk_user` WHERE (`user_name` LIKE '%ming' OR `user_name` LIKE 'xiao%')

区间查询

$where['id'] = array(array('gt',1),array('lt',10));查询id大于1小于10的;

$where['id'] = array(array('gt',32),array('lt',2),'or');查询id小于2和id大于30的; SELECT * FROM `mk_user` WHERE ( `id` > 32 OR `id` < 2 )

最后一个可以是AND、 OR或者 XOR运算符,如果不写,默认是AND运算。
区间查询的条件可以支持普通查询的所有表达式,也就是说类似LIKE、GT和EXP这样的表达式都可以支 持。另外区间查询还可以支持更多的条件,只要是针对一个字段的条件都可以写到一起

混合用法,同时支持数组和字符串

尽量不要用混合用法,混合用法的字符串查询如果不经过防注入就有可能被注入不安全的SQL语句
$where['id'] = array('gt',10);
$where['_string']='score>10';

统计查询count统计数量,max获取最大值,min获取最小值,avg平均值,sum求和

$data = M('user')->count();//统计user表数据的数量

//获取最大字段数据,必须必 传入要统计的字段名
$data = M('user')->max('id');
//获取最小字段数据,必须必 传入要统计的字段名
$data = M('user')->min( 'id' );
//获取平均值,必须必 传入要统计的字段名
$data = M('user')->avg('id');
//求和,  必须必 传入要统计的字段名
$data = M('user')->where('id<4')->sum('id');//把id<4的求和

create操作获取POST表单中的数据

$model = M('message');
$data =$model->create();

数据写入add()操作

add()操作,在执行add操作前有create操作,add可不带参数,否则必须要传入要添加的数据

$model = M('message');
$data =$model->create();
$res = $model->add();

//插入一条数据,返回插入的id号
$data = array(
    'user_name' => 'xiaoming',
    'nick_name' => '小明',
    'password' => '123456',
    'create_date' => date('Y-m-d H:i:s'),
    'update_date' => date('Y-m-d H:i:s'),

);
$user = M('user');
echo $user->add($data);

//插入多条数据,返回第一个插入的id号,因为addAll()把多为数组的数据合到一条数据里了可用getLastSql()查看Sql语句
$data = array(
    array(
        'user_name' => 'xiaohong',
        'nick_name' => '小红',
        'password' => '123456',
        'create_date' => date('Y-m-d H:i:s'),
        'update_date' => date('Y-m-d H:i:s'),
    ),
    array(
        'user_name' => 'xiaobai',
        'nick_name' => '小白',
        'password' => '123456',
        'create_date' => date('Y-m-d H:i:s'),
        'update_date' => date('Y-m-d H:i:s'),
    ),
);
echo M('user')->addAll($data);
echo M()->getLastSql();

显示页面Trace信息,可以查看自动创建的SQL语句信息

          修改config
‘SHOW_PAGE_TRACE’=>true,

数据读取

find操作,生成的有limit 1语句,只能查询一条数据
$data = $model->where('id=1')->find();//查询id=1的数据

select操作,以二维数组返回数据,可查询多条数据
$data = $model->where('id>=1')->select();

getField操作,查询字段的数据,可支持多条查询
$data = $model->where('id=1')->getField('username');
$data = $model->where('id>=1')->getField('id,username',true);

数据更新save()

$update['user_name'] = 'update';
$where['id'] = 1;
$data = M('User')->where($where)->save($update);//更新id等于1的user_name=update;

save()方法需要传入一个数组参数,数组的键表示要修改的数据字段名,值表示要修改的数据,也可以把修改的数据赋值给模型对象,这样就不用传参了
save()的返回值是数据表中受影响的行数,如果返回false表示更新失败,因此一定要使用恒等判断是否更新成功
$model = M('message');
$data['id']=1;
$data['username']='Green';
$res=$model->save($data);
if($res===false){
     echo 更新失败
}
setField可以更新个别字段的值
$res = $model->where('id=1')->setField('username','Tom');

数据删除delete()

delete()可删单个数据也可删多个数据,取决于删除条件
$model->where('id=5')->delete();//删除单个数据
$model->delete('1,2,5');//删除主键1,2和5的用户数据,只能传入主键
$model->where('status=0')->delete()//删除所有status字段值为0的用户数据
如果不传入数据则不会执行任何操作
如果想删除表中所有数据
$model->where('1')->delete();

连贯操作,放在select之前

1.order排序 order(字符串)多个条件用英文逗号隔开

$data = M('User')->order('id desc')->select();
$data = M('User')->order('id desc,score asc')->select();

2.field($string,false)$string传入多个字段名用英文逗号分开

$data = M('User')->field('id,user_name')->order('id desc')->select();只取id和user_name字段
$data = M('User')->field('id,user_name',true)->order('id desc')->select();开启了true,取id和user_name以外的

3.limit(start,length)显示数据的条数

$data = M('User')
    ->field('id,user_name',1)
    ->order('id desc')
    ->limit(5)     //从开始位置显示5条
    ->select();
 limit(2,5) //从第二条开始,显示五条

4.分页page(页码,每页的条数,默认20),不推荐使用这种进行分页,ThinkPHP提供了分页类

$data = M('User')
    ->page(1,5)
    ->select();

4.group()分组操作

$data = M('User')->field('user_name,count(*) as total')->group('user_name')->select();

5.having()条件

$data = M('User')->field('user_name,count(*) as total')->having('user_name="xiaoming"')
->group('user_name')->select();

6.多表查询 table方法 table(array('表名'=>'别名'))表名需要加前缀

$data = M()->table(array('mk_user'=>'user','mk_userinfo'=>'info'))->where('user.id=info.user_id')
->select();

7.多表查询join方法,join()支持字符串和数组

M('user')->join('mk_userinfo On mk_userinfo.user_id=mk_user.id')->select();//默认是左关联
M('user')->join('Right join mk_userinfo On mk_userinfo.user_id=mk_user.id')->select();//设置右关联
M('user')->join('inner join mk_userinfo On mk_userinfo.user_id=mk_user.id')->select();//设置内连接
M('user')->join(array('mk_userinfo On mk_userinfo.user_id=mk_user.id'))->select();//数组

8.多表查询 union查询 union("string array",true/false)

    M('User')
    ->field('user_name,id')
    ->union('select user_name,id from mk_user2')//把两张表里边相同的字段查询user_name查询出来
    ->select();

     union(array('field'=>'user_name','table'=>'mk_user2'),true)//开启true为unionall

9.过滤查询 distinct()

$data = M('user')->distinct(true)->field('user_name')->select();//过滤重复数据

命名范围的使用

先在模板中写好
protected $_scope = array(
/*
 * '命名范围的标识名'=array(
 *      '属性'=>'值'
 * 支持的方法有:where limit field order table page having group disinct
 * )
 */
'jige'=>array(
    'where' => array(
        'id'=>array('egt',30),
    ),
    'order' => 'id asc'
),
);

然后在控制器中调用
$user = D('User');
$data = $user->scope('jige')->select();
echo M()->getLastSql();//生成 SELECT * FROM `mk_user` WHERE `id` >= 30 ORDER BY id asc

如果想再加条件
class UserModel extends CommonModel{

    protected $_scope = array(
    'jige'=>array(
        'where' => array(
            'id'=>array('egt',30),
        ),
        'order' => 'id asc'
    ),
        'ziduan' => array(
            'field' => 'user_name,id'
        ),
    );
}
然后在控制器中调用
$data = $user->scope('jige,ziduan')->select();// SELECT `user_name`,`id` FROM `mk_user` WHERE `id` >=             
30 ORDER BY id asc

如果两个命名范围里的字段重复时则后边的覆盖前边的

而且调用命名范围后还可以使用连贯操作
$data = $user->scope('jige,ziduan')->where('user_name="xiaoming"')->select();// SELECT     
`user_name`,`id` FROM `mk_user` WHERE `id` >= 30 AND ( user_name="xiaoming ) ORDER BY id asc

-视图

系统变量与常量

{$Think.sever.script_name}//输出$_SERVER['SCRIPT_NAME']变量
{$Think.session.user_id}  //输出 $_SESSION['user_id']变量
{$Think.get.pageNumber}  //输出 $_GET['pageNumber']变量
{$Think.cookie.name}  //输出 $_Cookie['name']变量
常量
{$Think.const.PUB_CSS_URL}  //输出常量PUB_CSS_URL
{$Think.PUB_CSS_URL}  //也可也省略const

模板替换

模板里的from表单提交地址

//使用时把.去掉,因为写在我网页里不带点会直接被网站识别成ROOT没有前边的下划线了
__ROOT_._   ——— 会替换成当前网站的地址(不含域名)
__APP_._   ——— 替换成当前应用的URL地址(不含域名)
__MODULE_._   ——— 当前模块
__CONTROLLER_._  ——— 当前控制器)
__ACTION_._   ——— 当前操作
__SELF_._   ——— 当前操作
__APP_._   ——— 当前页面
__PUBLIC_._   ——— 当前网站的公共目录通常是/Public/

布局

全局配置方式
在当前模块的配置文件\Application\Home\Conf\config.php
'LAYOUT_ON'=>true,
'LAYOUT_NAME'=>'LAYOUT'
然后写layout.html
<html>
.....
.....
{__CONTENT__}
......
.....
</html>

//模板标签方式
<layout name='layout'>
<div id='center'>
    dfadfga g
</div>

-ThinkPHP路由

例如,当要访问前台用户登录的操作时,以默认的PATHINFO模式访问的URL地址如下:
http://localhost/index.php/Home/User/login
通过REWRITE模式和路由的结合,上述URL地址可以简写为: http://localhost/login
如果http://localhost/Home/login.程序首先通过URL确定当前模块为Home模块,然后在Home模块的路由规则表中对login进行匹配,成功则进入login操作,失败再去调用login控制器

如果http://localhost/login.因为ThinkPHP支持在URL中省略默认模块(Home已设定为默认),程序首先会将URL地址中的login作为模块名进行判断,当login模块不存在就进入默认的Home模块,在Home模块中进行路由匹配。当匹配成功,就进入login操作,失败则把login作为控制器继续判断

在Common\Conf\config.php中配置URL模式和默认模块
//URL模式
'URL_MODEL' => 2,
//定义允许访问的模块列表
'MODULE_ALLOW_LIST' => array('Home','Admin'),
//默认模块,由于ThinkPHP存在惯例配置,一般不用配置
//'DEFAULT_MODULE' => 'Home',
在Home\Conf\config.php中配置路由
//开启路由
'URL_ROUTER_ON' => true,
//配置路由规则
'URL_ROUTE_RULES' => array(
          'login' => 'User/login',
),

注意:在ThinkPHP的URL模式中,REWRITE去掉了URL地址中的入口文件index.php.但是需要额外配置Web服务器的重写规则才能正确访问。

1.打开Apache配置文件将加在rewrite模块的指令取消注释:LoadModule rewrite_module modules/mod_rewrite.so
2.修改目录权限,启用分布式配置文件:
<Directory "你的项目目录">
     ...
     AllowOverride All
</Directory>

而且要在项目里index.php同级目录里建一个.htaccess文件,文件内容如下
<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

--路由规则定义

1.路由定义

路由规则定义的两种格式:
'路由表达式'=>'路由地址和传入参数'
array('路由表达式','路由地址'[,'传入参数'][,'路由参数'])

① 路由到内部地址:
//方式一
'login' => 'User/login?x=1&y=2',
//方式二
array('login','User/login','x=1&y=2'),
//方式三(结合前两种方式,并将参数放入数组)
'login' => array('User/login',array('x'=>'1','y'=>'2')),

②路由到外部地址
//方式一
'itcast' => 'http://www.itcast.cn',
//方式二
'itcast' => array('http://www.itcast.cn'),
//方式三(指定重定向代码)301为默认重定向
'itcast' => array('http://www.itcast.cn',301)

③ 路由到本站点下的某个地址
//路由到本站点下的Public目录
'test'=>'/Public',
//路由到Admin模块User控制器login方法(需要REWRITE)
'test'=>'/Admin/User/login'

④ 为路由添加限制条件
//1.以html后缀方位才能生效
'login'=>array('User/login','',array('ext'=>'html')),
//2.只有通过GET方式请求才能生效
'login'=>array('User/login','',array('method'=>'GET')),
//3.函数返回值为true时才能生效
'login'=>array('User/login','',array('callback'=>function(){return isset($_GET['test'])})),

2.路由规则

ThinkPHP提供了规则路由、正则路由、静态路由

①  规则路由
//静态地址
'login' => 'User/login',
//静态地址与动态地址结合
'read/:id' => 'Blog/read',
//静态地址与动态地址结合
'read/:year/:month/:day' => 'Blog/read',
//全动态地址
':user/:blog' => 'Blog/read',
//在路由地址中引用动态参数:1代表:id
'read/:id' => 'Blog/read?id=:1',
//1.数字约束
'read/:id\d' => 'Blog/read',
//2.函数支持,进行md5处理
'read/:id\d|md5' => 'Blog/read',
//3.可选定义
'read/:year\d/[:month\d]' => 'Blog/read',
//4.规则排除add edit deleate
'read/:cate^add-edit-delete' => 'Blog/read',
//5.完全匹配,参数:id后边不能有任何参数
'read/:id$' => 'Blog/read',

② 正则路由
//匹配一个动态参数
'/^read\/(\d+)$/' => 'Blog/read?id=:1',
//匹配两个动态参数
'/^read\/(\d{4})\/(\d{2})$/' => 'Blog/read?id=:1&xx=:2',
//函数过滤,假设format_year为自定义函数
'/^read\/(\d{4})\/(\d{2})$/' => 'Blog/read?year=:1|format_year&xx=:2',

-数据过滤

1.输入过滤

I('变量类型.变量名',['默认值'],['过滤方法']),默认值为空字符串,‘过滤方法的默认值为htmlspecialchars,’可通过DEFAULT_FILTER更改

I函数的变量类型可参考手册 自定义过滤函数时,公共函数可以定义到Common目录的function.php中

//用I函数获取GET变量
echo I('get.name');
//原生语法
echo isset($_GET['name'] ? htmlspecialchars($_GET['name']) : '';

//获取GET变量并指定默认值
echo I('get.name','guest');
//获取GET变量并指定过滤参数,多个参数可用逗号分隔
echo I('get.name','','trim,htmlspecialchars')

//不用任何过滤方法
ehco I('get.name','','');
ehco I('get.name','','false');
//获取整个$_GET数组
echo I('get.','','trim');

//自动判断请求类型并获取变量
I('prame.name','','trim')
I('name','','trim');//简写

-数据验证

1.自动验证

自动验证是模型层提供的一种数据验证方法,使用create()方法创建对象数据对象时会自动进行数据对象时会自动进行数据验证,语法如下:
验证字段表示需要验证的表单字段,不一定是数据库字段,验证规则需要结合附加规则,验证条件和时机用于限制验证规则的生效条件

protected $_validate = array(
          array(验证字段1,验证规则,错误提示,[验证条件,附加规则,验证实际]),
          array(验证字段2,验证规则,错误提示,[验证条件,附加规则,验证实际]),

);

验证条件的三种可选值:0 当字段存在时验证(默认) 1 必须验证 2 值不为空验证
验证时机的三种可选值:0 在新增数据验证 1 在更新数据 2 在全部情况下验证(默认)
附加规则:regex(默认),function,equal...看手册
当附加规则为默认的正则验证时(regex),系统内置了一些常用的正则验证规则:require,email,url....等等

① 在模型类中定义该模型的自动验证规则
protected $_validate = array(
               //默认情况下用正则进行验证
               array('verifly','require','验证码不能为空'),
               //在新增时验证name字段是否为一
               array('name','','账号名称已经存在',0,‘unique’,1),
);

② 使用create()方法创建数据库对象时,会自动进行验证
//实例化User对象
$user = D("User");
if(!$user->create()){
     //如果创建失败、表示验证没有通过,输出错误提示信息
     die($user->getError());
     }else{
         //验证通过,可以进行其他数据操作
     }

③ create()可自动判断当前是新增还是编辑(通过表单隐藏域的主键信息来确定),还可以通过参数明确指定当前的时机
//实例化User对象
$user = D("User");
//当前验证时机为新增数据
if(!$user->create(I('post.'),1)){
          //验证没通过
     }else{
          //验证通过
     }

④ 我们可以自定义增加验证时机,例如指定登录操作的时机为4
protected $_validate = array(
     //所有时机都验证
     array('verify','require','验证码必须'),
     //仅在登录时验证
     array('name','checkName','账号错误',1,‘function’,'4')
);

2.自动完成

-自动完成是ThinkPHP提供的用来完成数据自动处理和过滤的方法,使用create方法创建数据对象时会自动完成数据处理。通常用来完成默认字段写入,字段安全过滤以及业务逻辑的自动处理等,使用方法和自动验证类似

protected $_auto array{
     array(完成字段1,完成规则,[完成时机,附加规则]),
     array(完成字段2,完成规则,[完成时机,附加规则])

}

完成时机三种可选值:1 新增数据,2 更新数据,3 所有情况
附加规则,function,callback...查手册

3.限制字段

在ThinkPHP的模型层中还可以指定当新增或更新数据时允许操作的字段,当表单中的字段不在定义范围内时将直接丢弃

//新增时允许操作的字段
protected $insertFields = array('account','password','nickname','email');
//更新时允许操作的字段
protected $updateFields = array('nickname','email');

4.表单令牌验证

浏览器提交表单时,经常发生同一个表单提交多次的情况,例如用户连续多次单击提交按钮,或者反复刷新提交页面,造成同一个表单连续提交多次,ThinkPHP支持表单令牌验证功能,可有效防止表单的重复提交。当开启表单令牌验证时,系统会在带有表单的模板文件里自动生成name="TOKEN_NAME"的隐藏域,用于保存令牌。

1.配置行为绑定,创建文件Application\Common\Conf\tags.php
//配置表单令牌行为绑定
'view_filter'=>array('Behavior\TokenBuildBehavior'),

2.在配置文件中开启令牌功能,打开config.php
//开启令牌验证
'TOKEN_ON'=>true,
          模型类在创建数据对象时自动进行表单令牌验证操作,如果没有使用create方法创建数据对象时,可以手动调用模型类中的autoCheckToken方法进行表单令牌检测。
if(IS_PORT){
     $model = M();
     if(!$model->autoCheckToken($_POST)){
          die('表单令牌验证失败');
     }
}

-ThinkPHP扩展功能

文件上传,此类的代码位于“\ThinkPHP\Library\Think\Upload.class.php”实例化后调用即可

public function test(){
//        if(IS_POST){
//            //实例化上传类
//            $upload = new \Think\Upload();
//            //设置附件上传大小
//            $upload->maxSize = 3145728;
//            //设置附件上传类型
//            $upload->exts = array('jpg','gif','png','jpeg');
//            //设置附件上传根目录
//            $upload->rootPath = './Public/uploads/';
//            //设置文件上传目录
//            $upload->savePath='';
//            //上传文件
//            $info = $upload->upload();
//            if(!$info){
//                //上传错误提示错误信息
//                $this->error($upload->getError());
//            }else{
//                //上传成功
//                $this->success('上传成功');
//            }
//        }
          //根据不同的编程习惯,文件上传类还支持在实例化时直接传参
        $config = array(
            'maxSize' => 3145728,
            'rootPath' => './Public/uploads/',
            'savePath' => '',
            'saveName' => array('uniqid',''),
            'exts' => array('jpg','gif','png','jpeg'),
            'autoSub' => true,
            'subName' => array('date','Ymd'),
        );
        $upload = new \Think\Upload($config);
        $this->display('test');
    }

-制作缩略图

    为图片生成缩略图,图像处理类的代码位于“ \ThinkPHP\Library\Think\Image.class.php ”实例化即可调用
public function testImage(){
    //实例化图像处理类
    $image = new \Think\Image();
    //打开图片文件
    $image->open('./Public/1421549016777.png');
    //按照原图比例生成一个最大为150*150的缩略图并保存为thumb.jpg
    $image->thumb(150,150,[可选值])->save('./Public/thumb.jpg');
}

缩略图生成效果选项:1等比例缩放,2缩放后填充类型,3居中裁剪类型,4左上角裁剪,5右下角裁剪,6固定尺寸缩放类型

1 条评论

  1. writeaessay

    Nicely put. Regards!

发表评论