Thinkphp教程

Thinkphp教程

1        熟悉Thinkphp

1.1   什么是Thinkphp

Thinkphp是一个开源的PHP框架,遵循Apache2开源协议发布。使用面向对象的开发结构和MVC模式,封装了CURD和一些常用操作,在模版引擎、缓存机制、认证机制和扩展性方面均有独特的表现。

 

1.2   学习Thinkphp需要具备什么样的条件

学习框架前,你需要了解PHP、数据库的基础知识,同时对面向对象编程有一定了解,如果这些你还不具备,建议你先看看基础知识。

Web开发除了掌握服务端脚本,客户端的JS、CSS等方面的知识也是必不可少的。所以我建议朋友们在开始使用框架时,先尽可能的充实自己,掌握基础知识。

开始后面的学习前,建议现把Thinkphp的开发手册看一遍,这样说到什么概念的时候你心中有数。

 

1.3   我希望了解更多关于Thinkphp的信息

你可以访问官方网站http://www.thinkphp.cn

建议下载Thinkphp的开发手册和API手册,便于查找相关信息。

 

1.4   Thinkphp入门

(1)    项目的创建

你可以到官方网站下载Thinkphp代码生成器,或者访问http://hi.baidu.com/yhustc下载代码生成器,代码生成器运行需要.NET 2.0支持。

运行代码生成器后选择菜单“项目”->“生产项目目录”,或者使用快捷键“Ctrl+G”打开项目目录生产程序,按要求填写配置信息即可。这里数据库相关的信息我们留空。

thinkphp1.0.2版本使用Conf\config.php作为配置文件,而非以前的Conf\_config.php,请自行修改项目生成的批处理程序,修改一下配置文件的文件名。事实上,thinkphp1.0.2版本有自动生成项目目录的功能,直接放置index.php到项目目录下,访问一下后项目其他目录自动生成。

 

(2)    编写Hello world示例

Thinkphp是单一入口模式,也就是说所有流程都是从index.php开始的。项目目录下的index.php我们称之为入口文件。你所编写的Action,使用http://server/project/index.php/Action/function的形式访问。执行index.php的时候,Thinkphp的dispatch模块会自动分析应该加载哪个Action,并调用相应的函数。

Hello world示例没有与数据库的交互,如果只是要输出一个“Hello world”的字符串的话,我们在index.php里面echo都可以了。不过这样的话没有达到演示框架的目的,我们按常规路线来搞:

如果直接访问http://server/project/index.php,框架默认调用IndexAction(这个默认的Action是可以配置的,详情参见Thinkphp开发手册),使用http://server/project/index.php/Action的形式,默认访问该Action的index方法。所有Action、Model以及模板文件都应该使用UTF8编码。我们在Lib\Action目录下编写一个IndexAction.class.php,内容如下:

<?php

class Index Actionextends Action

{

       function index()

       {

              echo “Hello world”;

       }

}

?>

       默认访问IndexAction的index方法,所以访问http://server/project/index.php和访问http://server/project/index.php/Index/index效果是一样的(Linux区分文件名大小写,所有应该确保Action名称大小写与文件名一致)。

页面输出Helloworld。 

       下面我们演示一下如何用模板输出变量。

       在Tpl目录下新建default目录,这是默认的模板,多模板的话就建多个文件夹。然后在default目录下新建Index目录,该目录名与Action对应。然后新建index.html,该文件名默认与调用的方法一致。编写index.html内容如下:

<b>{$str}</b>

然后我们修改开始编写的index方法,内容如下:

function index()

{

       $this->assign(“str”, “Hello world”);

       $this->display();

}

访问http://server/project/index.php,页面源码为<b>Hello world</b>。

 

2        Thinkphp的CURD

CURD需要涉及到数据库部分,而且模板显示内容一般也是跟数据库紧密集合的。所以准备了一个非常简单的BBS的例子。

先看一下数据库结构。

user表很简单,只记录用户名密码和上次登录时间。

column表记录BBS分区,category记录BBS版面。一个分区下面可以有多个版面。

page表记录BBS上的帖子。主题帖的pid为0,跟帖的pid为主题帖的id。

2.1  READ

涉及到数据库的话,就需要有Model。在Lib的Model目录下编写PageModel.class.php

<?php

/* Thinkphp 1.0的Model会自动分析数据库结构,所以写个空Model就OK了*/

class PageModelextends Model

{

}

?>

查询所有数据,在Lib的Action目录下编写PageAction.class.php内容如下

<?php

class PageActionextends Action

{

       function index()

       {

              $pagemodel = D(“Page”);

              $result =$pagemodel->findAll();

//第一个参数填写查询条件,第二个参数为结果字段

              dump($result);

}

}

?>

       如果只需要查一条记录,可以使用find方法

       function byid()

       {

              $pagemodel = D("Page");

              $result =$pagemodel->find("id='".$_GET["id"]."'");

              dump($result);

       }

       更复杂一点的查询,需要结合Model和HashMap的查询条件来实现。HashMap查询大家可以看看手册,自己多实验一下。这里我演示一下Model相关的查询。

       视图查询。在Lib\Model目录下编写PageViewModel.class.php如下

<?php

classPageViewModel extends Model{

       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"));

      

       // 定义视图主键名称

       Public function getPk() {

              return 'id';

       }

}

?>

       上面定义了一个视图,将Page的user_id与user表的id对应,这样我们就可以在页面中直接查看发帖的用户的用户名了。给PageAction实现一个pageview方法如下:

       function pageview()

       {

              $pageview =D("PageView");

              $result = $pageview->findAll();

              dump($result);

       }

       关联查询。关联查询有好几种关系,具体见手册,我这里演示一下关联的HAS_MANY。TP核心文件的Model.class.php 1238行,findAll应该有10个参数,早期版本的1.0RC1少了一个参数,请检查参数个数,如果只有9个参数,请在倒数第三个参数(true)前面加一个null;结合使用has_many和模板的sublist标签进行关联查询时,Model.class.php 1238行的findAll最后一个参数应该使用false,否则数据查不出来)

       我们定义一个ColumnModel.class.php,这是分区的数据表,每个分区下面有多个版面,是HAS_MANY的关系。

<?php

class ColumnModelextends Model{

       var $category; //这个变量用来存放查出来的多个版面信息

      

       var $_link = array( //设置关联关系

              array('mapping_type'=>HAS_MANY,

                     'class_name'=>'Category',

                     'foreign_key'=>'`pid`',

                     'mapping_name'=>'category'

                     )

              );

}

?>

       由于关联查询涉及到Category表,我们需要定义一个CategoryModel.class.php,内容很简单:

<?php

classCategoryModel extends Model

{

}

?>

       下面可以开始关联查找了。定义一个ColumnAction.class.php,内容如下:

<?php

class ColumnActionextends Action

{

       function index()

       {

              $column = D(“Column”);

              $result = $column->xfindAll();//xfind、xfindAll关联查询

              dump($result);

}

}

?>

       其他关联,比如BLOGS_TO之类的,大家可以举一反三,多实验几次就能明白了。

2.2  C操作

如何使用Model的add方法添加记录大家可以看看手册,这里我主要演示一下使用表格自动添加记录,后面将演示一下自动填充以及表格校验。

首先到tpl\default目录下添加一个名为Page的文件夹,添加一个add.html。这个是发表新主题的页面,内容如下(__URL__表示当前Action__APP__表示当前应用)注意:所有文件都要使用UTF8编码:

<h1>发表新主题</h1>

<formmethod=post action="__URL__/insert">

<table>

<tr>

<td>标题</td><td><input type=textname="title"/></td>

</tr>

<tr>

<td>内容</td><td><textareaname="content" cols="50"rows="10"></textarea></td>

</tr>

<tr>

<tdcolspan="2" align=center><input type=hiddenname="pid" value="0" /><input type=hiddenname="category_id" value="{$cateid}" /><inputtype=submit value="发表" /></td>

</tr>

</table>

</form>

需要注意的是,各个input的name默认跟数据表的字段同名,这样才能自动根据form的内容生产记录。由于是主题帖发表,所以pid的value直接设置成0(跟帖页面上的pid的value需要设置成主题帖的id)。category_id 表示当前帖子属于那个分区,这个是在用户进入分区发帖时设置的。

给PageAction添加一个add方法,用来显示发表主题的页面,内容如下:

function add()

{

       $this->assign(“cateid”,$_GET[“cid”]);

       $this->display();

}

       现在以及可以正确显示发帖页面了,下面就要开始编写insert方法,将帖子添加到数据库中

function insert()

{

       $Pagemodel = D("Page");

       $vo = $Pagemodel->create();

if(false === $vo) {

                    die($Pagemodel->getError());

       }

       $topicid = $Pagemodel->add(); //add方法会返回新添加的记录的主键值

       if($topicid)

       {

              echo "发表主题成功";

       }

       else

              throw_exception("发表主题失败");

}

下面我们修改一下PageModel,添加表格自动填充和校验的功能,修改后的PageModel.class.php文件如下

class PageModelextends Model

{

       var $_auto = array(

              array('user_id','getUser','ALL','function'),

              array('addtime','2007-12-22','ADD')

              );

      

       var $_validate = array(

              array('title','require','标题必须!'),

              array('content','require','内容必须!')

              );

}

       自动填充根据用户制定的规则填充数据表的指定字段,自动校验除了require以外,还可以使用正则表达式,详见手册。

2.3  U操作

U操作与C操作大同小异,主要是使用Model的save方法保持记录。不在赘述。

2.4   D操作

D操作注意是Model的delete方法,我们演示一下根据ID删除帖子的功能,编写PageAction的delete方法如下

function delete()

       $Pagemodel = D("Page");

       $id = $_REQUEST['id'];

if($Pagemodel ->deleteById($id))

       echo “删帖成功”;

else

       echo “删帖失败”;

}


 

 

3        Thinkphp的模板机制

关于模板的详细介绍,请看手册关于模板的章节。下面演示一下常用标签的使用。

最简单的是变量输出,这个在Helloworld里面以及演示过了,如果记不清楚如何输出变量,请参考第一节。

下面我们演示一下如何输出数组(对象)。可以通过配置DATA_RESULT_TYPE,设置返回结果的类型(1:对象,0:数组)。如果不配置,默认数据返回格式为数组。一般情况下,模板中的变量无需区分其数组还是对象,Thinkphp在赋值的时候会自动判断。

使用上一节的PageAction的byid方法,我们格式化输出帖子内容。

在Tpl\default\Page目录下使用utf-8编码建一个byid.html模板,内容如下(第一行导入标签库):

<tagLib name='cx,html' />

<html>

<head>

<title>Thinkphp Demo</title>

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

</head>

<body>

<table border="1">

<tr>

       <tdrowspan=2>{$vo.user_id}</td>

       <td>title:{$vo.title}</td>

</tr>

<tr>

       <td>

       content:<p>{$vo.content}</p>

       <p>addtime: {$vo.addtime}</p>

       </td>

</tr>

</table>

</body>

</html>

然后我们修改一下byid方法,将dump语句注释掉,添加:

$this->assign("vo",$result); //模板中我们使用的是vo变量

$this->display(); //加载模板,输出

下面演示一下volist的使用,同时我们演示一下include标签。

volist相当于for循环。很多朋友可能用过require(“header.htm”),require(“footer.htm”)这样的模板操作,include标签实际上就是这个作用。我们首先在Tpl\default目录下建立一个public目录,一些公用的文件我们放在这个目录下。

建立header.html内容如下:

<html>

<head>

<title>Thinkphp Demo</title>

<meta http-equiv="Content-Type"content="text/html; charset=utf-8">

</head>

<body>

建立footer.html内容如下:

<p align=”center”>copyright 2008yhustc</p>

</body>

</html>

       然后我们到Page的模板目录新建一个pageview.html,内容如下:

<tagLib name='cx,html' />

<include file="../Public/header" />

<volist name=”result” id=”vo”>

<p>

<table border="1">

<tr>

       <tdrowspan=2>{$vo.loginid}</td>

       <td>title:{$vo.title}</td>

</tr>

<tr>

       <td>

       content:<p>{$vo.content}</p>

       <p>addtime: {$vo.addtime}</p>

       </td>

</tr>

</table>

</p>

</volist>

<include file="../Public/footer" />

可以看到,其实就是把刚才显示单个帖子的页面放到一个volist标签里面就可以实现循环了。name是Action中将要赋值的变量,id是在volist内部使用的变量。

将pageview函数中的dump语句注释掉,添加:

$this->assign("result",$result); //模板中我们使用的是result变量

$this->display(); //加载模板,输出

翻页操作

要做内容列表输出有一个很重要的问题就是分页显示。用thinkphp做分页是很简单的。下面我们演示一下。

还是刚才的pageview,我们修改一下函数。在开始查询前,需要导入分页类,同时根据当前页数设置limit条件。完整的pageview函数如下:

function pageview()

{

$pageview = D("PageView");

              $count=$pageview->count(); //count函数参数是查询条件,默认没有where的条件限制

              import("ORG.Util.Page");//导入分页类

              if(!empty($_REQUEST['listRows'])){

                     $listRows  = $_REQUEST['listRows'];

              }else{

                     $listRows=2;//listRows标识每页显示多少条记录

              }

              $p=new Page($count,$listRows); //根据总数和每页显示记录数生成Page类的对象

              $result= $pageview->findAll('','*','id asc',$p->firstRow.','.$p->listRows);

              $page=$p->show();//page类的show方法生成翻页的字符串

              //dump($result);

              $this->assign("result",$result);//模板中我们使用的是vo变量

              $this->assign("page",$page);

              $this->display();//加载模板,输出

}

主要就是增加了生成翻页函数的操作,同时findAll函数修改一下调用方式,将limit条件传入。倒数第二行给一个叫page的模板变量赋值,所以我们也需要在模板中添加一个page。在</volist>下面一行添加{$page}。然后刷新页面,thinkphp自动生成了翻页链接。

内置list标签

如果只是单纯的进行列表操作,例如后台管理里面查看文章列表,使用list标签是个很方便的办法。我们试着将分区内容作为列表显示。

给ColumnAction增加一个listpage操作如下:

function listpage()

       {

              $column= D("Column");

              $result= $column->findAll();

              $this->assign("result",$result);

              $this->display();

       }

listpage操作很普通,$result是select出来的结果,将其赋值给模板中的result变量。现在看看模板的list标签如何写。Tpl\default\Column\listpage.html内容如下:

<tagLibname='cx,html' />

<includefile="../Public/header" />

<html:listid="columnlist" datasource="result" name="vo"show="id:编号,name:名称|80%"/>

<includefile="../Public/footer" />

主要是配置datasource和show两个熟悉。datasource就是刚才赋值的result。show是要显示的列。第一个是数据库select出来对应的字段,冒号后面的是标题,竖线后面的是列宽。如果需要将字段进行函数处理,在字段后用|function的形式调用。比如id|function:函数处理后的编号|20%。

访问一下页面,thinkphp自动生成了一个表格。你可以给这个表格指定css,也可以添加checkbox,添加action。这些内容可以通过RBAC管理系统的Node的模板部分学习。

多级列表

有的时候需要用到多级列表。比如显示一个BBS的分区,然后分区下面有很多版面。这个时候可以使用sublist标签。

将Column的index操作的dump操作注释掉,添加:

$this->assign("result",$result);

$this->display();

通过上面的学习,相信大家使用volist来显示Column的列表已经不是问题了。现在我们需要做的,及时在Column列表的volist标签中嵌入一个sublist标签,Tpl\default\Column\index.html内容如下:

<tagLibname='cx,html' />

<includefile="../Public/header" />

<volistid="cvo" name="result">

<!-- 栏目模块开始 -->

<tablewidth="100%">

<tbody>

<tr><td> </td></tr>

<!-- 栏目的标题行开始 -->

<tr><tdstyle="padding-left:10px;background-color:Gray">

<h2style="color:White">{$cvo.name}</h2>

</td></tr>

<!-- 栏目的标题行结束 -->

<!-- 分类的标题行开始 -->

<tr><td>论坛</td></tr>

<!-- 分类的标题行结束 -->

</tbody>

<!-- 分类列表开始 -->

<sublistname="cvo['category']" id="categoryvo">

<tbody>

<tr>

        <td style="padding-left:10px">

                     <h3>{$categoryvo.name}</h3>

                     <div>{$categoryvo.description}</div>

        </td>

</tr>

</tbody>

</sublist>

<!-- 分类列表结束 -->

 

</table>

<!-- 栏目模块结束 -->

</volist>

<includefile="../Public/footer" />

       result赋值到模板中,然后现在迭代过程中起作用的变量是cvo,所以在sublist赋值时,应该使用cvo的category属性。注意:thinkphpsublist在进行模板解析时,会自动判断name属性的变量是数组还是对象,但是这段代码有点小问题(1.0的早期版本有这个问题),所以请确定你的返回结果类型,如果是数组形式,写成<sublist name="cvo['category']",如果是对象形式,写成<sublist name="cvo.category",不要让thinkphp自动判断,否则无法运行。

 

 

4        Thinkphp的角色控制(RBAC)

RBAC其实思想很简单,在配置文件中,如果USER_AUTH_ON值为true,那么在用户登录时会获取一个ACCESS_LIST(默认情况。强认证的情况下每访问一个页面获取一次),这个LIST里面的内容就是用户允许范围的Action\function组成的一个数组。用户每打开一个页面时,先检查该Action是否在NOT_AUTH_MODULE里面,如果不在无需验证的范围内,则开始匹配ACCESS_LIST里面的内容(在REQUIRE_AUTH_MODULE范围内的也需要验证)。如果用户访问的Action\function不在ACCESS_LIST里面则显示错误信息。如果用户没有登录,则自动跳转到GATEWAY页面,默认是PublicAction的login操作。(这里有个问题大家要注意:如果使用RBAC进行权限控制,'Public'一定要放在'NOT_AUTH_MODULE'中,或者定义REQUIRE_AUTH_MODULE,否则会有什么情况呢?没有权限就跳转到Public\login,然后Public不在'NOT_AUTH_MODULE'中啊,好Public也是要校验权限的,又跳转到Public\login……这样一直死循环…….因为REQUIRE_AUTH_MODULENOT_AUTH_MODULE是互补的,一般定义一个就可以了)

讲了这么多,让我们来实际操作一下吧。

我们先给这个BBS定义几个简单的权限控制规则:普通用户和高级用户都可以查看PageAction的pageview页面,只有高级用户才可以发表主题。

到www.thinkphp.cn下载一个RBAC管理系统,导入SQL后上面那个图里面的几个表就建好了,本地跑起来,设置一下项目权限(你需要根据你的user表做一些修改,RBAC项目压缩包里面有一个我写的说明文件)。怎么使用这个系统,有录像演示。

(下面蓝色部分在导入的SQL里面数据已经有了,你可以用RBAC管理系统查看一下设置)

添加好节点web(请输入你使用的项目名),然后进入节点web添加模块Page,进入Page添加操作pageviewadd。在mysqluser表里面添加两个记录,分别是user1user2,然后就是给项目添加角色了,在RBAC管理系统里面添加普通用户和高级用户两个角色,然后将两个用户分配到两个组,添加授权。两个角色都授予操作pageview的权利,高级用户授予操作add的权利。

权限分配好以后,剩下的就是需要识别用户以及在用户登录是获取这个权限信息了。在进行操作前,建议打开调试模式,及在配置文件中添加'debug_mode'=> true,然后删除Temp目录下的~app.php文件清除配置缓存,这样的话可以显示详细的错误信息,比如“没有权限”“模板不存在之类的”。

识别用户靠登录啊,刚才以及说过了,如果用户没有登录,则自动跳转到GATEWAY页面,默认是PublicAction的login操作,所以我们需要添加这个操作先。(由于这里内容多了点,我只摘录一些关键部分说明一下,其他内容可以直接看源码)

PublicAction.php

function login()

{

if(!isset($_SESSION[C('USER_AUTH_KEY')])||$_SESSION[C('USER_AUTH_KEY')]==0){

     $this->display();

     return ;

}else {

redirect(__APP__);

}

}

C('USER_AUTH_KEY')什么意思,大家看看手册的C函数部分。

跟自己写的验证一样,如果保存用户ID的session值不存在,或者是个非法值,显示login页面,否则说明用户已经登录了,跳转到项目首页。

login的内容无法就是一个登录框,这个大家应该自己可以搞定。

RBAC的关键部分在于验证用户登录的函数里面。PublicAction.class.php

function checkLogin()

    {

        // 生成认证Map 条件

              // 这里使用用户名、密码和状态的方式进行认证

              Import("ORG.Util.HashMap");// 导入HashMap

              $map = newHashMap();

              $map->put("loginid",$_POST['name']);//login页面POST来的用户名

              $map->put("passwd",md5($_POST['password']));//POST来的密码

              //put里面的loginid和passwd需要跟数据库字段对应

              $authInfo =RBAC::authenticate($map); //委托认证,实际上就是一个select

 

              if(false ===$authInfo) {

                     echo '登录失败,请检查用户名和密码是否有误!';

              }else {

                     // 设置认证识别号,根据自己的情况看是否需要导入Session类

                     session_register(C('USER_AUTH_KEY'));

                     session_register('loginid');

                     $_SESSION[C('USER_AUTH_KEY')]= $authInfo["id"];

                     $_SESSION["loginid"]= $authInfo["loginid"];

                    

                     RBAC::saveAccessList();//获取并保存用户访问权限列表

                    

                     dump($_SESSION);

                     echo strtoupper(APP_NAME).””.strtoupper(MODULE_NAME).” ”.strtoupper(ACTION_NAME);

              }

}

在托管认证的过程中,你将loginid和passwd传入了,默认使用User表来进行查询,所以你需要在Model目录下添加一个UserModel.class.php,否则显示RBAC的认证数据源无法生成对象。dump一下session的内容,如果登录成功,你应该可以看到ACCESS_LIST了,仔细看看里面的内容,你就能对RBAC的机制恍然大悟了,呵呵,每次访问一个链接的时候,TP自动用当前的项目名、模块名、操作名匹配这个array,来确定你是否有权限访问这个页面。

使用不同的用户登陆,访问Page\pageview和Page\add,看看有什么效果呢?写到这里,你应该对RBAC的权限控制机制有一定了解了吧?更详细的内容,你可以调试一下RBAC.class.php这个文件。

 

 

写给ThinkPHPer的话

接触thinkphp有几个月了,07年10月份开始接触,写了个CMS系统,当时TP的教程和手册都不是很完善,所以我萌生了给TP0.98版本写教程的念头。无奈自己文字功底太差了,而且是第一次写教程,写了一整下午才写了一点。同时TP也在飞速发展,我还没写第二节,TP已经出1.0版本了,呵呵。然后过了一段时间开始写这个教程,期间thinkphp仍在不断的完善,里面有很多红色字体的内容都是针对老版本需要注意的地方,新版本基本上都修复了。但是由于平时自己事情也多,所以一直拖到了3月份才写完,后面两节的录像有时间再补上吧,十分抱歉。

不断的有新人加入TP,他们也逐渐形成TP社区的骨干,这是令人很欣慰的,流年的努力也得到了肯定。同时有更加多的朋友们开始在TP的社区汇聚,问题总是提不完的,虽然社区里面有很多热心的朋友负责解答,但是我想,最好的办法还是靠自己,靠自己的努力解决你遇到的问题,虽然可能有点花时间。

正如我在0.98的教程里面写过的,教程能写明白的东西太少了,大家需要的是一个入门,然后自己来研究,来发现其精髓,这样不管TP发展的多么迅速,抑或是以后你接触其他新的技术,总能与时俱进的。

关于thinkphp,给大家一些建议:

1、刚接触TP时,先看手册,不要急于研究案例源码或拿着源码看到一个操作后开始搜索手册。我看tp的时候花了一个下午看手册,看不懂也继续看。因为很多内容都是前后相辅相成的。等你看完一遍,对TP里面的一些概念有个大概的了解,再回过头来看的时候,你就能有一个全局的了解了。等你有一定基础了,再看源码不迟。

2、熟练使用trace功能,这里面有页面运行的各种信息,包括ORM操作生成的SQL语句。开发是时候将DEBUG_MODE设置成true,可以显示trace信息,如果不喜欢将trace信息显示在页面上,你还可以设置将trace信息保存在指定文件里面。详细情况查看TP的手册。

3、习惯调试。这里的调试不是上面的调试模式的意思,呵呵。写程序最基本的就是学会调试,尤其是使用框架的时候,很多操作都隐藏了,那么出现了问题更加需要跟踪到里面去看个究竟。养成调试的习惯,你才能透过现象看本质。搞明白了里面的情况后觉得TP不符合你的要求?想怎么改就怎么改!

4、时刻注意文件编码。TP使用UTF8编码,如果是普通的PHP文件,顶多是出现乱码,这时候编码错误很容易发现。但是模板的编码错误就是很隐蔽的了。模板的标签解析要求UTF8编码,出现GB编码的汉字的话,可能导致标签无法解析。我有一次用select标签,发现死活无法生成表格,把模板类调试了个遍,发现输入是正确的,XML解析结果始终不对,后来看了一下文件编码才恍然大悟。

5、多到TP的论坛转转。论坛上有很多热心的人将他们遇到的一些问题以及解决方法,或者是使用TP的一些心得帖上来,对你也许很有用哦。同时你提出的问题也回得到大家的耐心解答的。

6、尽信书不如无书,实践才能出真知。有了一定基础后,多写点东西,比反复看手册有效的多啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值