ThinkPHP代码分析核心.docx

上传人:b****6 文档编号:8183878 上传时间:2023-01-29 格式:DOCX 页数:23 大小:50.73KB
下载 相关 举报
ThinkPHP代码分析核心.docx_第1页
第1页 / 共23页
ThinkPHP代码分析核心.docx_第2页
第2页 / 共23页
ThinkPHP代码分析核心.docx_第3页
第3页 / 共23页
ThinkPHP代码分析核心.docx_第4页
第4页 / 共23页
ThinkPHP代码分析核心.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

ThinkPHP代码分析核心.docx

《ThinkPHP代码分析核心.docx》由会员分享,可在线阅读,更多相关《ThinkPHP代码分析核心.docx(23页珍藏版)》请在冰豆网上搜索。

ThinkPHP代码分析核心.docx

ThinkPHP代码分析核心

前言

TP的手册相当多,其实不必再出这样的贴子,论技术,我也是菜鸟一个,同时也在学习当中。

看到论坛上多了不少新朋友,不少在抱怨手册看不懂,那我就姑且抛砖引玉,尝试与新朋友们更简单地、手把手地进入TP的应用中去。

讲解过程中有错的地方,大家帮忙指正。

这个系列,初步定下的目标为,从零开始,以TP示例中心中的Form为例进行讲解,以实践为主,理论为辅,将TP的最基本内容逛一遍,至少让我们一起学会如何进行最简单的对数据进行查、增、改、删操作并输出到模板。

由于我们说的是循序渐进,所以我用步骤式来说明,只要一步一步跟着做,相信聪明的你在使用过程中就会明白TP的应用了。

注意:

以下的步骤,仅仅是TP灵活的布署方式其中一种,实际开发中可以根据自己的情况去另行设定。

至于为什么那样做,我们会在最后再作总结,我觉得先实操然后再进行说明比较容易明白。

以下不再重复解释。

一快速开始一个项目

名词解释:

项目:

你要开发的系统,称之为项目。

入口文件:

你可以理解为这个项目的唯一的一道门,以后所有的操作都会通过这道门去执行处理。

不必理会什么意思,你甚至可以先把它看成是就是入口文件

TP:

ThinkPHP框架的简称

1下载正式版

2拟好你的项目名称,我们这里以Myapp为项目名称

3在www根目录下,将TP框架所有文件全部复制过去,文件夹名称是ThinkPHP

4与ThinkPHP同级新建一个文件夹,起名为Myapp,也就是项目名称

5在www根目录下,创建一个PHP文件,起名,这就是入口文件

入口文件代码:

ThinkPHP');

Myapp');

/');

如上面的index操作。

通常一个应用模块中,会有若干操作(function)需要有与用户交互的页面,这就需要用到模板输出,TP本身已内置了一套具有TP特色的,很强大易扩展但应用非常方便兼简单的模板引擎。

在应有模块中,如果某个操作是需要页面显示的,只要对应在Myapp/Tpl/default/里建立一个文件夹,文件夹以应用模块的名称来命名,然后在这个文件夹下,建立一个以这个function名称来命名的html文件,就可以在这个方法中使用$this->display()方法来直接调用该模板。

(当然也可以调用其它模块下的其它模板或显式指定模板文件位置和名称,由于是循序渐进式的学习,就让我们先忽略吧)了解这些理论后,我们先简单实操一下这些知识。

1在Myapp/Tpl/default/下建立一个文件夹,根据应用模块的名称,我们将这个文件夹命名为Index

2在Myapp/Tpl/default/Index/下建立一个html文件,根据操作名称,我们命名该文件为

classIndexActionextendsAction{

publicfunctionindex(){

$value='hello,ThinkPHP';

$this->assign('name',$value);

$this->display();

}

}

>

代码知识要点(摘自手册:

ThinkPHP模板指南,此后的知识要点均来自TP官方手册,不再申明)

在Action类里面使用assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值。

$this->assign('name',$value);

taccess文件,内容是

RewriteEngineon

RewriteCond%{REQUEST_FILENAME}!

-d

RewriteCond%{REQUEST_FILENAME}!

-f

RewriteRule^(.*)$$1[QSA,PT,L]

如果你的服务器环境支持rewrite,使用就可以正常访问到Index模块的index操作了。

此后我们的学习中用到的URL,都是假定你使用了rewrite的情况

第六节CURD知识之一C创建(create)

从这一节开始,我们就要涉及到数据库操作,TP对数据库的操作非常简便,以下是一些基础知识讲解。

名词解析:

CURD:

代表数据库四个基本操作:

创建:

create,更新:

update,读取:

read,删除:

delete

模型对象:

即数据对象,你项目里每一个Model类文件都会对应着一个数据表(或者视图),模型与数据表存在一种映射关系。

TP约定了命名要遵循一定的规范,如果不符合,则需要根据情况进行额外的相应设置。

例如Model类的tableName属性

----模型(M)

同时也在Myapp/Lib/Action/下添加了一个Index应用模块和写下了一个index操作----控制器(C)并且在Tpl目录下建立了与之对应的模板目录Index及模板文件-------视图(V)MVC模式的开发已体现了出来。

tdweb曾简明扼要地概括了TP中这三者的关系,

C的作用,就是从M中取得数据到V,

使用TP以表单提交数据到库,流程和你所了解的表单提交没有什么区别,只是TP简化了数据操作的处理过程。

我们在实际操作中体会一下。

先来看看我们所定义的数据表form的字段:

'id',下面主要说说function与callback这两个附加规则。

protected$_auto=array(

array('create_time','time','ADD','function'),

);

上面create_time代表了要处理的字段,填充内容是time,附加规则是function使用函数,填充条件是ADD新增时处理,那么整行代码表示对create_time字段在新增的时候使time函数作为该字段的值进行自动填充。

再看一个function作为附加规则的例子

protected$_auto=array(

array('password','md5','ADD','function'),

);

当使用function作为附加规则时,第二个填充内容就代表了这个因子是一个函数名称,该函数的参数就是代表填充字段的值,比如password的值是123456,则上面的代码会先将这个值使用函数md5('123456'),这样处理后再插入到数据表中去。

对于function(函数)和callback(回调方法)理论是一样的,只不过一个是表示填充内容所写的是函数名,另一个是表示填充内容是类中的方法名。

函数可以是PHP5内置函数或你自己所写的函数。

而callback是当前模型类所能调用的一个方法。

有关数据填充方面的详细资料,请参看官方使用手册《ThinkPHP数据操作指南》

2打开Myapp/Tpl/default/Index/文件,我们修改代码将form写进去

DOCTYPEHTMLPUBLIC"-[

()">返回]');

}

}

}步1:

将根目录中的原剪切并粘贴到Myapp文件夹下。

更改代码为:

/ThinkPHP');

;

/');

taccess文件复制一份粘贴到Myapp目录下。

步3:

将Cache目录,Temp目录,Data目录清空。

说明2第五节中对于URL访问的默认模式

在dev版默认配置中,dispatch即URL调度功能是关闭的,所以在默认模式下,要访问Index模块的index操作,地址应是:

m=index&a=index,m指的是模块变量(Model),a指的是操作变量(Action)。

如果要使用类似第五节中的moduleName/actionName方式,则要在文件里设置DISPATCH_ON为true;并且,也只有开启了此功能后,URL_MODEL的设置才会有效。

(在上面的章节我们提及过,可以设置URL_MODEL为2来使用rewrite功能去除显示

所以,现在我们的代码是

if(!

defined('THINK_PATH'))exit();

returnarray(

'DB_TYPE'=>'mysql',那么再来看看我们所定义的数据表form的字段:

'id',使用ADD|UPDATE|ALL会无效的(TO流年大哥:

TP代码还有一个特色就是函数或方法的命名很符合语言使用习惯,原来的add,update,all很直观,易记,可惜没了)

array('field','填充内容','填充条件','附加规则',[额外参数])

alias_import($alias,$classfile='')快速定义和别名导入

这是新增的函数,我尝试注解一下,不正确请指正。

该函数可以动态设置文件列表导入和直接导入文件,常会用到的文件别名有

当要引入已定义别名的文件,我们只要直接在参数中传递别名就行了。

别名可以自行在ThinkPHP/Common/中扩充。

除了使用已定义的别名外,也可以使用动态指定。

alias_import('zzg',APP_PATH.'/Lib/ORG/');

或一次引入多个文件

$ailias=array(

'Abc'=>APP_PATH.'/Lib/ORG/',

'Efg'=>APP_PATH.'/Lib/Other/',

);

alias_import($ailias);

注:

指定文件或别名不存在时会返回false

类似的函数还有

import($class,$baseUrl='',$ext='.')

由于性能问题,这个方式以后不再支持

这是ThinkPHP内建的类库和文件导入的一个函数,具有缓存和检测机制,相同的文件不会重复导入,冲突时会提示错误。

使用这方法时,系统会自动识别导入类库文件的位置:

Think代表TP框架基类库即ThinkPHP/Lib/Think目录

ORG代表第三方公共类库即ThinkPHP/Lib/ORG目录

TP的约定是Think、ORG等导入的是以系统(TP)基类库为相对起始目录,否则就认为是项目(Myapp)应用类库为起始目录。

注意1使用时要注意文件名的大小写

注意2Import会自动将.转换为/,如果文件名中含有.,则要将.改为#才能正常导入。

注意3导入的类文件后缀默认是.

2第三方框架类库导入:

vendor($class,$baseUrl='',$ext='.php'),

起始目录统一是ThinkPHP/Vendor默认后缀是.php

注:

vendor也使用了Import函数。

因此...

说明3,原来的模板文件保持不变,因为我们已启用了DISPATCH_ON开关。

仅将Myapp/Lib/Action/如下

classIndexActionextendsAction{

publicfunctionindex()

{

$Form=D("Form")->select();[

()">返回]');

}

$rs=$Form->add();[

()">返回]');

}

}

}ox{width:

600px;margin:

10pxauto;border:

1pxdashed#e8e8e8;padding:

5px;}

.submit{height:

2em;padding:

05px;cursor:

pointer;}

标题:

邮箱:

内容:

{$}:

{$}

-----------由{$}发表于:

{$|date='Y-m-d',###}

内容:

{$}

在浏览器中输入,可以看到现

在已将数据显示在模板了

这时我们只要每输入一条数据信息,就会按照id倒序的方式显示在模板上。

现在模板显示已设定好,我们来一起学习查询的各种方法:

先了解一个TP词汇:

连贯操作

所谓连贯操作,是TP利用__call方法来实现的一些特殊的Model类方法,可以对数据对象连续调用数个方法(参数)来设定特定的条件,然后执行最终所指定的操作,这类特定方法的命名都很直观易记,主要方法(参数)有

用于查询表达式的

'field'参数支持如下键名

table指定表名称,可以跨表访问,若不填则是当前DAO

distinct指定是否只列出不重复数据,如果想列出不重复数据,则为true,不填则无此功能

field指定要搜索的字段,不填则为*

join填写join,可以支持数组或者直接使用字符串,如果是字符串,那么只支持LEFTJOIN,如果想使用RIGHTJOIN,那么只能使用数组定义,并且必须写清RIGHTJOINwhere指定查询条件

where可以多说点,功能很多。

首先说最简单的字符串查询,直接执行就OK了。

使用数组指定查询条件

$whereArr=array(

"account"=>"tdweb",

"home"=>"China"

);

$options=array(

"where"=>$whereArr

);

$Dao->select($options);

这样默认是查询SELECT*FROM`test`WHERE(`account`='tdweb')AND(`home`='China')是查询相等条件的。

那如果我想查询like条件怎么办

解决方法之一是定义LIKE_MATCH_FIELDS配置,这里指明要进行like查询的字段。

现在我们稍微改下程序

publicfunctiontestDb()

{

C('LIKE_MATCH_FIELDS',"account");

$Dao=D("Test");

$whereArr=array(

"account"=>"tdweb",

"home"=>"China"

);

$options=array(

"where"=>$whereArr

);

dump($Dao->select($options));

echo$Dao->getLastSql();

}

得到的SQL就是SELECT*FROM`test`WHERE(`account`LIKE'%tdweb%')AND(`home`='China')

接着,可以看如下代码

publicfunctiontestDb()

{

$Dao=D("Test");

$whereArr=array(

"account"=>array("eq","tdweb"),

"home"=>array("like","%Chi%"),

"age"=>array("between","1,3")

);

$options=array(

"where"=>$whereArr

);

dump($Dao->select($options));

echo$Dao->getLastSql();

}

这里的$whereArr定义为一个二级数组,没一个字段都定义了一个数组,这样可以支持更高级复杂的查询。

其中支持的关键字:

EQ相等

NEQ不相等

GT大于

EGT不大于

LT小于

ELT不小于

NOTLIKE不相似

LIKE相似

NULL空

NOTNULL不为空

EXP使用自己写的表达式

同样,select也支持一个名为“_after_select”的回调方法

如何去消化这段内容,将在下一节以我们的实例Myapp中实操去体会。

第8节视图查询

ThinkPHP提供了视图查询应用,利用视图查询可以将多个数据表的字段内容按需要进行指定和筛选,组织成一个基于这些数据表的视图模型,然后就可以通过该模型直接进行多表联合查询,非常方便和简单。

例如在项目中,我们定义有三个表,

user用户基础表,

user_info用户详细信息表,

dept部门分类表

现在我们需要获取某个用户信息,该信息要包括用户的帐号名称和相关资料与及所在部门的名称,这时候我们可以利用视图查询进行处理。

让我们在实际操作中去体会。

1构建一个新项目并进行相关配置(可参考前面的教程,这里省略)

2创建一个数据库tpview,并添加这三个表

用户表

CREATETABLE`think_user`(

`id`int(11)unsignedNOTNULLAUTO_INCREMENTCOMMENT'ID编号',

`name`varchar(20)NOTNULLCOMMENT'帐户',

`password`varchar(32)NOTNULLCOMMENT'密码',

`dept_id`smallint(6)unsignedNOTNULL,

`status`tinyint

(1)unsignedNOTNULLDEFAULT'1'COMMENT'开放状态',

PRIMARYKEY(`id`)

)ENGINE=MyISAMDEFAULTCHARSET=utf8COMMENT='会员表'AUTO_INCREMENT=2;

INSERTINTO`think_user`(`id`,`name`,`password`,`dept_id`,`status`)VALUES

(1,'zzguo28','123456',2,1);

用户信息表

CREATETABLE`think_user_info`(

`user_id`int(11)NOTNULLCOMMENT'用户id',

`nick_name`varchar(30)NOTNULLCOMMENT'用户昵称',

`email`varchar(100)NOTNULLCOMMENT'邮箱地址',

`address`varchar(100)NOTNULLCOMMENT'详细地址',

`gender`tinyint

(1)NOTNULLDEFAULT'0'COMMENT'性别',

`mobile`varchar(100)NOTNULLCOMMENT'手机号码',

`telephone`varchar(100)NOTNULLCOMMENT'电话号码',

KEY`user_id`(`user_id`)

)ENGINE=MyISAMDEFAULTCHARSET=utf8ROW_FORMAT=DYNAMICCOMMENT='用户信息表';

INSERTINTO`think_user_info`(`user_id`,`nick_name`,`email`,`address`,`gender`,`mobile`,`telephone`)VALUES

(1,'国路think街号

部门分类表

CREATETABLE`think_dept`(

`id`smallint(3)NOTNULLAUTO_INCREMENT,

`name`varchar(50)NOTNULL,

PRIMARYKEY(`id`)

)ENGINE=MyISAMDEFAULTCHARSET=utf8AUTO_INCREMENT=4;

INSERTINTO`think_dept`(`id`,`name`)VALUES

(1,'开发部'),

(2,'销售部'),

(3,'财务部');

3在项目/Lib/Model下创建这三个表的基础模型Model

本示例没涉及到验证等其它功能,所以只要简单定义测可,例如

classUserModelextendsModel{

}

>

其实视图模型对应的数据表并非一定要有相应的的基础模型,但是建议您创建,这样单表和视图都可以操作。

4创建视图模型,代码如下,详细注解见其后:

(最新svn上已增加动态扩展模型功能,使用新版需要将protected属性改为public属性,建议使用动态扩展功能去使用视图查询,而不再是本教程的继承方式。

那样使用会更灵活。

import('ViewModel');

classUserViewModelextendsViewModel{

protected$viewFields=array(

'User'=>array('id','name','_as'=>'u','_type'=>'left'),

'UserInfo'=>array('email','mobile','_as'=>'ui','_on'=>'='),

'Dept'=>array('name'=>'dept','_on'=>'='),

);

}

>

逐行解释上面的代码:

在行2代码中,因为版已将视图查询分离出原Model类,所以这里需要使用import方法引入了视图模型类。

行3代码中,定义了该模型名称为UserViewModel,视图模型的名称Model前的命名是随意的,只是为了有别于其它模型,通常我们会以xxxViewModel这样的方式去命名。

并且一定要继承ViewModel。

版无需再设置模型的viewModel属性为true,只要继承ViewModel则可)

第四行代码$viewFields属性表示视图模型包含的字段,每个元素定义了各个数据表或者模型所需的字段。

格式是

protected$viewFields=array(

'表名'=>array('所需字段','_as'=>'别名定义','_on'=>'筛选条件','_type'=>'指定join类型,支持right,inner,left三种'),

);

是否留意到行7代码中的'name'=>'dept',因为User模型里面已经存在了一个name字段,所以我们通过这种方式把Dept模型的name字段映射为d

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1