Thinkphp教程1熟悉Thinkphp1.1什么是ThinkphpThinkphp是一个开源的PHP框架,遵循Apache2开源协议发布。使用面向对象的开发结构和MVC模式,封装了CURD和一些常用操作,在模版引擎、缓存机制、认证机制和扩展性方面均有独特的表现。1.2学习Thinkphp需要具备什么样的条件学习框架前,你需要了解PHP、数据库的基础知识,同时对面向对象编程有一定了解,如果这些你还不具备,建议你先看看基础知识。Web开发除了掌握服务端脚本,客户端的JS、CSS等方面的知识也是必不可少的。所以我建议朋友们在开始使用框架时,先尽可能的充实自己,掌握基础知识。开始后面的学习前,建议现把Thinkphp的开发手册看一遍,这样说到什么概念的时候你心中有数。1.3我希望了解更多关于Thinkphp的信息你可以访问官方网站。建议下载Thinkphp的开发手册和API手册,便于查找相关信息。1.4Thinkphp入门(1)项目的创建你可以到官方网站下载Thinkphp代码生成器,或者访问下载代码生成器,代码生成器运行需要.NET2.0支持。运行代码生成器后选择菜单“项目”-“生产项目目录”,或者使用快捷键“Ctrl+G”打开项目目录生产程序,按要求填写配置信息即可。这里数据库相关的信息我们留空。thinkphp1.0.2版本使用Conf\config.php作为配置文件,而非以前的Conf\_config.php,请自行修改项目生成的批处理程序,修改一下配置文件的文件名。事实上,thinkphp1.0.2版本有自动生成项目目录的功能,直接放置index.php到项目目录下,访问一下后项目其他目录自动生成。(2)编写Helloworld示例Thinkphp是单一入口模式,也就是说所有流程都是从index.php开始的。项目目录下的index.php我们称之为入口文件。你所编写的Action,使用的形式访问。执行index.php的时候,Thinkphp的dispatch模块会自动分析应该加载哪个Action,并调用相应的函数。Helloworld示例没有与数据库的交互,如果只是要输出一个“Helloworld”的字符串的话,我们在index.php里面echo都可以了。不过这样的话没有达到演示框架的目的,我们按常规路线来搞:如果直接访问,框架默认调用IndexAction(这个默认的Action是可以配置的,详情参见Thinkphp开发手册),使用的形式,默认访问该Action的index方法。所有Action、Model以及模板文件都应该使用UTF8编码。我们在Lib\Action目录下编写一个IndexAction.class.php,内容如下:?phpclassIndexActionextendsAction{functionindex(){echo“Helloworld”;}}?默认访问IndexAction的index方法,所以访问和访问效果是一样的(Linux区分文件名大小写,所有应该确保Action名称大小写与文件名一致)。页面输出Helloworld。下面我们演示一下如何用模板输出变量。在Tpl目录下新建default目录,这是默认的模板,多模板的话就建多个文件夹。然后在default目录下新建Index目录,该目录名与Action对应。然后新建index.html,该文件名默认与调用的方法一致。编写index.html内容如下:b{$str}/b然后我们修改开始编写的index方法,内容如下:functionindex(){$this-assign(“str”,“Helloworld”);$this-display();}访问,页面源码为bHelloworld/b。2Thinkphp的CURDCURD需要涉及到数据库部分,而且模板显示内容一般也是跟数据库紧密集合的。所以准备了一个非常简单的BBS的例子。先看一下数据库结构。user表很简单,只记录用户名密码和上次登录时间。column表记录BBS分区,category记录BBS版面。一个分区下面可以有多个版面。page表记录BBS上的帖子。主题帖的pid为0,跟帖的pid为主题帖的id。2.1READ涉及到数据库的话,就需要有Model。在Lib的Model目录下编写PageModel.class.php?php/*Thinkphp1.0的Model会自动分析数据库结构,所以写个空Model就OK了*/classPageModelextendsModel{}?查询所有数据,在Lib的Action目录下编写PageAction.class.php内容如下?phpclassPageActionextendsAction{functionindex(){$pagemodel=D(“Page”);$result=$pagemodel-findAll();//第一个参数填写查询条件,第二个参数为结果字段dump($result);}}?如果只需要查一条记录,可以使用find方法functionbyid(){$pagemodel=D(Page);$result=$pagemodel-find(id='.$_GET[id].');dump($result);}更复杂一点的查询,需要结合Model和HashMap的查询条件来实现。HashMap查询大家可以看看手册,自己多实验一下。这里我演示一下Model相关的查询。视图查询。在Lib\Model目录下编写PageViewModel.class.php如下?phpclassPageViewModelextendsModel{protected$viewModel=true;var$masterModel='Page';//定义视图中的字段protected$viewFields=array('Page'=array('id','title','category_id','content','user_id','addtime','lastmodify','pid'),'User'=array('loginid'));//定义基础查询条件protected$viewCondition=array(Page.user_id=array('eqf',User.id));//定义视图主键名称PublicfunctiongetPk(){return'id';}}?上面定义了一个视图,将Page的user_id与user表的id对应,这样我们就可以在页面中直接查看发帖的用户的用户名了。给PageAction实现一个pageview方法如下:functionpageview(){$pageview=D(PageView);$result=$pageview-findAll();dump($result);}关联查询。关联查询有好几种关系,具体见手册,我这里演示一下关联的HAS_MANY。(TP核心文件的Model.class.php1238行,findAll应该有10个参数,早期版本的1.0RC1少了一个参数,请检查参数个数,如果只有9个参数,请在倒数第三个参数(true)前面加一个null;结合使用has_many和模板的sublist标签进行关联查询时,Model.class.php1238行的findAll最后一个参数应该使用false,否则数据查不出来)我们定义一个ColumnModel.class.php,这是分区的数据表,每个分区下面有多个版面,是HAS_MANY的关系。?phpclassColumnModelextendsModel{var$category;//这个变量用来存放查出来的多个版面信息var$_link=array(//设置关联关系array('mapping_type'=HAS_MANY,'class_name'='Category','foreign_key'='`pid`','mapping_name'='category'));}?由于关联查询涉及到Category表,我们需要定义一个CategoryModel.class.php,内容很简单:?phpclassCategoryModelextendsModel{}?下面可以开始关联查找了。定义一个ColumnAction.class.php,内容如下:?phpclassColumnActionextendsAction{functionindex(){$column=D(“Column”);$result=$column-xfindAll();//xfind、xfindAll关联查询dump($result);}}?其他关联,比如BLOGS_TO之类的,大家可以举一反三,多实验几次就能明白了。2.2C操作如何使用Model的add方法添加记录大家可以看看手册,这里我主要演示一下使用表格自动添加记录,后面将演示一下自动填充以及表格校验。首先到tpl\default目录下添加一个名为Page的文件夹,添加一个add.html。这个是发表新主题的页面,内容如下(__URL__表示当前Action,__APP__表示当前应用)注意:所有文件都要使用UTF8编码:h1发表新主题/h1formmethod=postaction=__URL__/inserttabletrtd标题/tdtdinputtype=textname=title//td/trtrtd内容/tdtdtextareaname=contentcols=50rows=10/textarea/td/trtrtdcolspan=2align=centerinputtype=hiddenname=pidvalue=0/inputtype=hiddenname=category_idvalue={$cateid}/inputtype=submitvalue=发表//td/tr/table/form需要注意的是,各个input的name默认跟数据表的字段同名,这样才能自动根据form的内容生产记录。由于是主题帖发表,所以pid的value直接设置成0(跟帖页面上的pid的value需要设置成主题帖的id)。category_id表示当前帖子属于那个分区,这个是在用户进入分区发帖时设置的。给PageAction添加一个add方法,用来显示发表主题的页面,内容如下:functionadd(){$this-assign(“cateid”,$_GET[“cid”]);$this-display();}现在以及可以正确显示发帖页面了,下面就要开始编写insert方法,将帖子添加到数据库中functioninsert(){$Pagemodel=D(Page);$vo=$Pagemodel-create();if(false===$vo){die($Pagemodel-getError());}$topicid=$Pagemodel-add();//add方法会返回新添加的记录的主键值if($topicid){echo发表主题成功;}elsethrow_exception(发表主题失败);