您的位置:首页 > 编程语言 > PHP开发

ThinkPHP开发指南(二)高级特性-thinkphp

2011-11-28 02:20 239 查看
ThinkPHP后台治理具备项目自动创建的功能,首先确保后台治理项目运行正常。
自动创建的作用是根据节点治理里面添加的项目名称自动创建项目的目录结构、进口文件、配置文件等,免往了手动创建众多目录和文件的麻烦。
要使用自动创建功能,请确认你的网站根目录具有可写权限。
然后,在后台的节点治理添加项目节点,添加成功后,在列表的操纵部分点击创建连接,系统就会自动创建项目目录结构,并把后台治理的配置文件复制到添加的项目中,假如需要修改,请手动进行修改。
留意:
为了安全,在后台删除项目并不会删除项目目录结构,假如需要,请手动对目录结构进行删除操纵。
模块自动天生
ThinkPHP后台治理具备自动天生模块的功能,条件是你已经为模块创建好了相应的符合配置要求的数据表。
这一功能比较适合功能单一的模块操纵,Action类、Dao类和Vo类均使用同名数据表。
要自动创建模块,请首先在节点治理里面添加模块节点,然后点击创建连接自动创建模块。
模块自动天生的文件包括,项目的Action类(没有任何操纵方法)、Dao类(没有任何方法,直接继续Dao类)和Vo类(已经包含数据表对应字段的属性定义),以及模版的模块目录。
请放心,假如已经存在创建好的项目类库文件,系统不会再次重新天生。
表单验证类表单验证类
ThinkPHP内置了表单验证类来提供对表单提交的数据进行验证,这里指的是后台验证,而不是客户真个验证,客户端验证请参考Js类库的CheckForm类。
表单验证类位于ORG.Text.Validation,通过正则的方式对数据进行验证,并定义了一些常用的验证规则。
包括:
1. require 字段必须
2. email 邮箱
3. phone 电话号码
4. mobile 手机号码
5. url URL地址
6. currency 货币
7. number 数字
8. zip 邮政编码
9. qq QQ号码
10. integer 整数
11. double 浮点数
12. english 英文
13. chinese 中文
14. username 用户名
15. password 密码
验证类的使用方法:
复制PHP内容到剪贴板 PHP代码:import(ORG.Text.Validation);
$validation = Validation: :getInstance();
if(!$validation->check($_POST[\'username\'],\’username\’)) {
$this->error(\’用户名不符合规范!\’);
}
使用自定义的正则式验证 复制PHP内容到剪贴板
PHP代码:if(!$validation->check($_POST[\'name\'],\’/^[a-z]w{4,}$/i\’)) {
$this->error( \’用户名必须是以字母打头,且5位以上!\’);
}
在ThinkPHP框架中,你还可以单独定义一个_validation方法,用来对表单数据进行验证。
系统在执行操纵之前,会检查该模块是否存在_validation方法,假如存在,会自动调用进行验证。
一个典型的_validation方法定义如下,当验证没有通过的时候,系统会返回$this->error信息给客户端。
复制PHP内容到剪贴板
PHP代码:function _validation()
{
$validation = Validation: :getInstance();
//对所有需要验证的数据进行验证
if(isset($_POST[\'name\'])) {
if(!$validation->check($_POST[\'name\'],\’require\’)) {
$this->error = \’用户名必须\’;
return false;
}
}
if(isset($_POST[\'password\']) ) {
if(!$validation->check($_POST[\'password\'],\’require\’)) {
$this->error = \’密码有误\’;
return false;
}
}
return true;
}
Vo自动验证ThinkPHP还支持Vo自动验证,可以无需定义_validation方法来进行验证,只需要在Vo类定义的时候使用_validation属性定义需要验证的属性,在表单提交的时候系统会完成自动验证过程。
Vo类的_validation属性定义格式如下:
复制PHP内容到剪贴板 PHP代码:var $_validate = array(
array(content,require,内容不能为空),
array(email,email,Email格式错误),
array(userId,/^d+$/,必须是数字),
);
_validate
属性是一个二维数组,每个元素定义了一个验证因子,由三个元素组成且必须,第一个元素是要验证的属性名,第二个元素是验证规则,支持定义规则和正则,第三个元素是出错提示信息。
系统会在根据表单提交数据创建Vo对象的时候自动对_validate 定义的内容进行验证。
例如:
复制PHP内容到剪贴板 PHP代码:$dao
= D(Blog);
$vo = $dao->createVo();
if(false === $vo) {
$this->error($dao->error);
}
Vo自动填充在Vo类定义 $_auto 属性,可以完成Vo自动填充功能,用来处理默认值和其他系统写进字段。
定义方法:
复制PHP内容到剪贴板
PHP代码:var $_auto = array (
array(\’status\’,\’1\’,\’ADD\’),
array(\’mTime\’,\’time\’,\’UPDATE\’),
array(\’type\’,\’0\’,\’ALL\’),
);
每个自动填充项是一个数组,依次代表 字段名称、填充值和填充类型(ALL 始终 ADD 新增时填充 UPDATE
更新时填充)。
填充类型留空默认表示ADD。
在使用Dao的CreateVo方法创建Vo对象的时候,假如存在_auto定义,就会进行自动填充。
填充值假如是函数就填充函数返回值,否则就按照字符串填充。
PS:
该自动填充可能会覆盖表单提交项目。
其目的是为了防止表单非法提交字段。
前置和后置操纵通用前置和后置操纵
在ThinkPHP中,你可以给任何一个操纵定义前置和后置操纵方法。
前置操纵的定义就是在当前操纵方法的前面添加_before_前缀,而后置操纵的定义就是在当前操纵方法的前面添加_after_前缀。
例如,我们已经给UserAction定义了一个del操纵方法,我们可以定义:
_before_del() 在del操纵之前执行
_after_del() 在del操纵之后执行(del操纵正常执行完毕)
内置前置和后置操纵
另外,假如使用系统内置的insert和update操纵的话,会首先检查是否存在_operation方法,这个方法是系统在表单提交时候的默认前置操纵。
_operation方法没有任何参数,主要是用来检测表单的提交数据。
在insert或者update执行完毕后,系统会检查是否存在_trigger方法,这个方法是系统默认的数据更新触发器方法。
_trigger方法只有一个参数,也就是要保存的Vo对象。
列表过滤方法
假如你使用系统内置的index方法,系统还会检查_filter方法,该方法负责对列表数据进行过滤,当你的列表需要针对不同的用户进行判定和过滤的时候,这个方法非常有效。
分页类使用ThinkPHP内置了分页类,位于 ORG.Util.Page ,使用举例:
复制PHP内容到剪贴板 PHP代码:$dao =
D(\’User\’);
$count = $dao->getCount();
import(ORG.Util.Page);
if(!empty($_REQUEST[\'listRows\'])) {
$listRows = $_REQUEST[\'listRows\'];
}else{
$listRows=4;
}
$p= new Page($count,$listRows);
$list=$dao->findAll(\’\',\’\',\’*\’,\’id
asc\’,$p->firstRow.\’,\’.$p->listRows);
$page= $p->show();
$this->assign(page,$page);
$this->assign(userList,$list);
在模版文件中,使用标签 复制PHP内容到剪贴板 PHP代码:{$page}
就可用输出分页
显示效果
其中每页显示的记录数、页数等信息均可以修改。
假如需要定制分页的显示,可以使用下面的方式输出分页 复制PHP内容到剪贴板 PHP代码:$page= $p->show(true);
$this->assign(page,$page);
然后,在模版文件里面自己添加下面的变量
1. $page[\'totalRows\'] // 总的记录数
2. $page[\'upPage\'] // 上一页链接
3. $page[\'downPage\'] // 下一页链接
4. $page[\'totalPages\'] // 总页数
5. $page[\'firstPage\'] // 第一页链接
6. $page[\'endPage\'] // 最后一页链接
7. $page[\'nextPages\'] //下一个链接页(比如说设置每页显示5页链接,这里指的是下一个5页)
8. $page[\'prePages\'] // 上一个链接页
9. $page[\'linkPages\'] // 当前链接页
10. $page[\'nowPage\'] // 当前页
不过,目前这种方式还是存在一定不足,更好的方式是自己扩展一个Page类来定制输出。
关联查询操纵关于ThinkPHP的关联查询支持。
目前支持的表间关联方式包括三种:
1、ONE_TO_ONE ( 包括HAS_ONE 和 BELONGS_TO )
2、ONE_TO_MANY( 包括HAS_MANY 和 BELONGS_TO)
3、MANY_TO_MANY
Dao类增加了一个xfind() 方法用于直接获取带关联记录的返回结果,而 getRelation() 方法用于获取已经返回记录的关联记录(集)。
xfind的参数和find方法保持不变,区别在于xfind方法会一起返回关联记录,而find方法默认不返回关联记录。
find方法最后增加了一个relation参数,用以控制是否进行关联查询。
xfind方法仅仅是find方法的一个引用。
relation参数支持false(不进行关联查询)、true(进行所有关联查询)和array(只查询某个关联)。
举例:
复制PHP内容到剪贴板 PHP代码:$dao->find(id=2); // 返回id为2的记录
$dao->xfind(id=2); // 返回id为2的记录,并同时返回其关联记录(假如有定义)
假如不是使用find方法进行查询,可以配合getRelation方法进行关联记录的查询。
例如:
复制PHP内容到剪贴板 PHP代码:$user = $dao->getById($id);
$user = $dao->getRelation($user);
// 或者使用下面的方法
$user = $dao->getById($id,\’\',\’*\’,\’\',true);
同样,增加了xFindAll方法进行关联查询(返回Volist对象),而findAll方法默认不进行关联查询。
例如:
复制PHP内容到剪贴板 PHP代码:$list = $dao->findAll(type=1); //查询type为1的用户
$list = $dao->xFindAll(type=1); // 查询并返回关联记录
关联查询需要Vo类定义_link 属性配合,例如UserVo中定义如下关联信息:
复制PHP内容到剪贴板 PHP代码:var $_link =
array(
// 每个用户都有一个个人档案
array( \’mapping_type\’=>HAS_ONE,
\’class_name\’=>\’Profile\’,
\’foreign_key\’=>\’userId\’,
\’mapping_name\’=>\’profile\’,
),
// 每个用户有多个文章
array( \’mapping_type\’=>HAS_MANY,
\’class_name\’=>\’Article\’,
\’foreign_key\’=>\’userId\’,
\’mapping_name\’=>\’articles\’,
\’mapping_order\’=>\’cTime desc\’),
// 每个用户都属于一个部分
array( \’mapping_type\’=>BELONGS_TO,
\’class_name\’=>\’Dept\’,
\’foreign_key\’=>\’userId\’,
\’mapping_name\’=>\’dept\’),
// 每个用户可以属于多个组,每个组可以有多个用户
array( \’mapping_type\’=>MANY_TO_MANY,
\’class_name\’=>\’Group\’,
\’mapping_name\’=>\’groups\’,
\’foreign_key\’=>\’userId\’,
\’relation_foreign_key\’=>\’goupId\’,
\’relation_table\’=>\’think_gourpUser\’)
);
而getRelation方法,则用于获取已经查询到的Vo对象的某个关联记录 复制PHP内容到剪贴板 PHP代码:$vo =
$dao->getRelation($vo,HAS_MANY,\’articles\’);
关于映射关系的定义,还有一些高级默认规则,除了mapping_type、class_name 和mapping_name
三个属性必须外,其他都是可选的。
另外,还可以包括mapping_order、condition、mapping_limit等高级属性。
默认规则
外键的默认规则是当前Vo对象名称+id,例如:
UserVo对应的可能是表think_user (留意:
think只是一个表前缀,可以随意配置)
那么think_user表的外键默以为 user_id,假如不是,就必须在定义表间映射关系的时候定义 foreign_key 。
同样的道理,对于多对多的情况,relation_foreign_key 的规则相同。
多对多的中间表默认表规则如下:
假如think_user 和 think_group 存在一个对应的中间表,默认的表名应该是
假如是由group来操纵关联表,中间表应该是
think_group_user,假如是从user表来操纵,那么应该是think_user_group,也就是说,多对多关联的设置,必须有一个Vo类里面需要显式定义中间表,否则双向操纵会出错。
中间表无需另外的id主键(但是这并不影响中间表的操纵),通常只是由 user_id 和 group_id 构成。
另外一个潜规则,由于表间映射关系可以定义condition属性,通常都是通过外键来获取关联数据,但是假如你定义了condition属性,那么就会重新使用condition的条件来获取关联表的数据。
在HAS_MANY 和MANY_TO_MANY情况下,可以使用mapping_order 和 mapping_limit
进行记录的排序和获取部分数据。
HAS_ONE 和 BELONGS_TO 永远都只会返回最多一条记录。
另外除了MANY_TO_MANY之外,其他映射关系可以使用 mapping_fields 来返回你需要的关联表字段。
关于自引用关联
假如Vo类的_link属性里面对于 class_name 为自身的情况就属于自引用关联。
通常用于从属关系的关联,例如,某个用户是另外一个用户的领导,某个节点下面有多个子节点这样的应用情况。
对于这样的情况,ThinkPHP增加了一个parent_key属性来定义,该属性在自引用方式下面有效。
例如NodeVo中有如下定义:
复制PHP内容到剪贴板
PHP代码://每个节点具有多个子节点
var $_link = array(
array( \’mapping_type\’=>HAS_MANY,
\’class_name\’=>\’Node\’,
\’foreign_key\’=>\’id\’,
\’parent_key\’=>\’pid\’,
\’mapping_name\’=>\’sub\’,
\’mapping_order\’=>\’seqNo asc\’),
);
parent_key
默认名称为parent_id,假如不是则需要指定。
权限控制ThinkPHP以基于Spring的Acegi安全系统作为参考原型,并做了简化,以适合目前的ThinkPHP结构,提供了一个多层的、可定制的安全体系来为应用开发提供安全控制。
安全体系中主要有:
安全拦截器
认证治理器
决策访问治理器
运行身份治理器
安全拦截器
安全拦截器就比如一道道门,在系统的安全防护系统中可能存在很多不同的安全控制环节,一旦某个环节你未通过安全体系认证,那么安全拦截器就会实施拦截。
认证治理器
防护体系的第一道门就是认证治理器,认证治理器负责决定你是谁,一般它通过验证你的主体(通常是一个用户名)和你的凭证(通常是一个密码),或者更多的资料来做到。
更简单的说,认证治理器验证你的身份是否在安全防护体系授权范围之内。
访问决策治理
固然通过了认证治理器的身份验证,但是并不代表你可以在系统里面肆意妄为,由于你还需要通过访问决策治理这道门。
访问决策治理器对用户进行授权,通过考虑你的身份认证信息和与受保护资源关联的安全属性决定是是否可以进进系统的某个模块,和进行某项操纵。
例如,安全规则规定只有主管才答应访问某个模块,而你并没有被授予主管权限,那么安全拦截器会拦截你的访问操纵。
决策访问治理器不能单独运行,必须首先依靠认证治理器进行身份确认,因此,在加载访问决策过滤器的时候已经包含了认证治理器和决策访问治理器。
为了满足应用的不同需要,ThinkPHP在进行访问决策治理的时候采用两种模式:
登录模式和即时模式。
登录模式,系统在用户登录的时候读取改用户所具备的授权信息到Session,下次不再重新获取授权信息。
也就是说即使治理员对该用户进行了权限修改,用户也必须在下次登录后才能生效。
即时模式就是为了解决上面的题目,在每次访问系统的模块或者操纵时候,进行即使验证该用户是否具有该模块和操纵的授权,从更高程度上保障了系统的安全。
运行身份治理器
运行身份治理器的用处在大多数应用系统中是有限的,例如某个操纵和模块需要多个身份的安全需求,运行身份治理器可以用另一个身份替换你目前的身份,从而答应你访问应用系统内部更深处的受保护对象。
这一层安全体系目前的RBAC插件中尚未实现。
早先RBAC组件是集成在ThinkPHP框架中的,从0.9版本引进了插件机制后,已经把RBAC组件转换成插件使用,以方便用户替换或者扩展,而且在调用接口上也更加方便。
要启用RBAC插件,请在项目配置文件_appConfig.php(请留意:
项目配置文件名是以App命名的支持多种格式,运行时候系统会自动天生一个定义文件,最新的版本中自动天生的定义文件名是_appConfig.php
,请留意更新) 中设置
USER_AUTH_ON 为True
并设置认证类型USER_AUTH_TYPE
1 普通认证(认证一次)
2 高级认证(实时认证)
不设置默以为1
认证识别名USER_AUTH_KEY
是用于检查用户是否经过身份认证的标识,一旦用户经过系统认证,系统会把该用户编号保存在$_SESSION[USER_AUTH_KEY]中
为了满足应用系统的需要,RBAC插件中可以设置
REQUIRE_AUTH_MODULE 需要认证的模块
NOT_AUTH_MODULE 无需认证的模块
多个模块之间用逗号分割
假如某个模块需要认证,但是用户还没有经过身份认证,就会跳转到
USER_AUTH_GATEWAY 认证网关,例如 /Public/login
验证地址就是:
项目进口文件URL地址/Public/login
假设认证网关的验证操纵地址是/Public/CheckLogin,可以在public模块的checkLogin操纵中采用如下方式进行认证:
<?php
// 天生认证Map条件
// 这里使用用户名、密码和状态的方式进行认证
$map = new HashMap();
$map->put(name,$_POST[\'name\']);
$map->put(password,$_POST[\'password\']);
$map->put(status,1);
$authInfo = RBAC: : authenticate($map);
if(false === $authInfo) {
$this->assign(\’error\’,\’登录失败,请检查用户名和密码是否有误!\’);
}else {
// 设置认证识别名
Session: :set(USER_AUTH_KEY,$authInfo->id);
//获取并保存用户访问权限列表
RBAC: :saveAccessList();
// 登录成功,页面跳转
$this->assign(message,\’登录成功!\’);
$this->assign(jumpUrl,\’http://www.topthink.com.cn\’);
}
$this->forward();
?>
RBAC的委托认证方法
authenticate($map,$dao=\’UserDao\’,$provider=USER_AUTH_PROVIDER)
方法是静态方法,支持三个参数,其中第一个认证条件$map是必须的,可以灵活地控制需要认证的字段。
第二个参数是进行认证的Dao类,默认是UserDao类
第三个参数是委托方式 由 USER_AUTH_PROVIDER 设置委托认证治理器的委托方式,目前支持的是
DaoAuthentictionProvider 通过数据库进行认证。
在应用系统的开发过程中,只需要设置相关的配置项和添加上面的认证方法,其他的认证和决策访问就由RBAC插件的AccessDecision方法自动完成了。
系统会在执行某个模块的操纵时候,首先判定该模块是否需要认证,假如需要认证并且已经登录,就会获取当前用户的权限列表判定是否具有当前模块确当前操纵权限,并进行相应的提示。
接下来就是在框架总后台设置相关项目的模块和操纵权限了。
首先,在总治理后台(ThinkPHP自带的Admin项目)的节点治理添加相关项目、模块和操纵,作为权限治理的节点。
假如需要设置公共的操纵,可以使用Public模块,所有属于Public模块的操纵对所有模块都有效。
添加完成项目治理节点后,就在权限治理里面对某个用户组设置相关权限(包括项目权限、模块权限和操纵权限)
以后需要授权就把用户添加到某个权限组就可以了,同一个用户可以属于多个权限组。
授权和认证功能涉及到四个数据表,DB_PREFIX为配置文件中设置的数据库前缀
DB_PREFIX_group 权限组表
DB_PREFIX_groupuser 组-用户关联表
DB_PREFIX_access 访问权限表
DB_PREFIX_node 权限节点表
ThinkPHP后台治理的权限授权图示:
标签:方法,模块,定义,剪贴板,系统,项目,权限,节点,表单,用户,属性,内容,安全,你的,代码,时候,就会,多个,数据,方式
关键字:
thinkphp,thinkphp
验证码,thinkphp 分页,thinkphp 文件上传,thinkphp session,thinkphp
success,thinkphp搭建cms,thinkphp1.5,thinkphp基础,thinkphp
特性
相关资讯:
ThinkPHP开发指南(二) 高级特性 – PHPChina
9条回复-发帖时间:2007年5月25日本篇主要用于添加一些ThinkPHP的高级开发特性,为了不影响阅读,把每个小主题单独列出来,比较清晰一
些,有兴趣的依次往下面看了,呵呵~1楼 项目自动创建和模块自动生

使用thinkPHP做注册程序的实例

登录界面:

数据库和数据表的结构

具体的操作步骤如下:
第一步:入口文件index.php内容 (此文件基本是属于固定的格式)
<?php
define(\’THINK_PATH\’,\’./ThinkPHP/\’);
define(\’APP_NAME\’,\’MyApp\’);
define(\’APP_PAHT\’,\’./MyApp/\’);
require_once
THINK_PATH.\’ThinkPHP.php\’;
$app=new App();
$app->run();
?>
第二步:Active文件夹中的IndexAction.class.php文件内容
<?php
class IndexAction extends Action
{
public function
Index()
{
$this->display();//渲染到模板index.html
}
// 生成验证码
public function
verify()//这是一个固定的格式
{
import(\”ORG.Util.Image\”);
Image::buildImageVerify();
}
//检验验证码是否正确
public function verifyCheck()
{
if
(md5($_POST[\'verifyTest\']) !=
Session::get(\’verify\’))
{
die(\’验证码错误\’); //如果验证码不对就退出程序
}
}
function insert()
{
header(\’Content-Type:text/html;
charset=utf-8\’);//防止出现乱码
$this->verifyCheck();//调用本类的函数,
$Pagemodel =
D(\”user\”);
$vo = $Pagemodel->create();
if(false === $vo)
die($Pagemodel->getError());
$topicid = $Pagemodel->add();
//add方法会返回新添加的记录的主键值
if($topicid) echo \”数据库添加成功\”;
else
throw_exception(\”数据库添加失败\”);
}
}
?>
第三步:写模板文件,也就是写LIB文件夹中的HTML文件
<!DOCTYPE html PUBLIC \”-//W3C//DTD XHTML 1.0 Transitional//EN\” \”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\”>
<html
xmlns=\”http://www.w3.org/1999/xhtml\”>
<head>
<meta
http-equiv=\”Content-Type\” content=\”text/html; charset=utf-8\”
/>
<title>无标题文档</title>
<style
type=\”text/css\”>
#form1
{
width:250px;
height:250px;
margin:20px
auto;
border:1px #039 solid;
padding:20px
20px;
}
</style>
<script
type=\’text/javascript\’>
function
freshVerify()
{
document.getElementByIdx(\’verifyImg\’).src=\’__URL__/verify/\’+Math.random();
}
</script>
</head>
<body>
<form
name=\”form1\” method=\”post\” action=\”__URL__/insert\”>
注册帐号:<br
/><br />
帐号:<input maxlength=\”16\” /><br /><br
/>
密码:<input type=\”password\” maxlength=\”16\” /><br /><br
/>
Q  Q:<input type=\”text\” maxlength=\”16\”
/><br /><br />
验证码:<input type=\’text\’ name=\’verifyTest\’ size=\”5\”>
<img
style=\’cursor:pointer\’ title=\’刷新验证码\’ src=\’__URL__/verify\’ id=\’verifyImg\’
onClick=\’freshVerify()\’/> <br /><br />
<input type=\”submit\” value=\”提交\” />
<input value=\”重置\”
/>
</form>
</body>
</html>
注意:
1、也就是一个form,action=\”__URL__/insert\”表示提交到当前Action类(即IndexAction.class.php文件中)的insert函数;
2、此模板(静态网页)中的各个name要与user数据表的各个字段是一样的名字,否则在insert函数中数据不能自动进库。
3、验证码的刷新由静态网页负责。值相等由IndexAction类的verifyCheck()负责。
第四步:写Model类,在model目录中,文件名为:UserModel.class.php
<?php
class UserModel extends Model
{
var
$_validate=array
(
array(\’user\’,\’require\’,\’账号不能为空\’,1),
array(\’qq\’,\’number\’,\’QQ号必须是数字,注册失败!\’,2),
array(\’user\’,\’\',\’此帐号己经存在!\’,0,\’unique\’,\’add\’)
);
var
$_auto=array
(
array(\’password\’,\’md5\’,\’add\’,\’function\’),
//array(\’create_time\’,\’time\’,\’add\’,\’function\’),
此句只能填充时间戳
array(\’create_time\’,\’zhongguo_time\’,\’add\’,\’callback\’)
//填充年月日时分秒只能用callback,不能用function
);
function zhongguo_time() //此函数只能放在本模块中,否则调用不到
{
return date(\”Y-m-d
H:i:s\”);
}
}
?>
注解:
1、文件名,类名必须用user,因为数据库中对应的是user表;
2、其实只要写一个框架就行了:
class UserModel extends Model
{
}
但为什么还要var $_validate=array()和var $_auto=array()呢?那是因为:
var $_validate=array()是自动验证的意思,var $_auto=array()是自动填充的意思。
自动验证就是验证数据的格式是否正确,自动填充就是你不输入的值,它自动给你灌进去,比如\’create_time\’建立时间,我们在模板中没有这个,但这里它就自动进库了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PHP 职场 休闲 Thinkphp