数据库操作之数据表模型和基础模型,ThinkPHP学习
- 编辑:大富豪棋牌游戏下载 -数据库操作之数据表模型和基础模型,ThinkPHP学习
ThinkPHP 提供了八个 Model 类,供别的的 Model 进行后续。Model 类中是 MVC 中的模型类,它是调用 漫长层 的上层类。感觉那样描述难点多多,不过有如何情势啊?可是,这几个 Model 有的时候不可能满意大家的片段需要,因而大家需求自定义一个 Model 类出来,然而自定义的 Model 相符要持续 TP 提供的 Model 类,而把大家自定义的 Model 类作为大家项目中的 Model 基类。作者怎么感到小编在说绕口令,等等...小编有一点晕。
//TP 恶补ing...
这两天相比绕风趣味地学习PHP,看完了部分底蕴语法、学会了动用SMACR-VY模版,进而看了ThinkPHP框架,
风姿洒脱、定义数据表模型
此框架的刚劲超过笔者的奇异,它的RO奥迪Q5真是强,还也可能有内置的CRUD,比JAVA的框架更智能。
猥琐的须要
1.模子映射
造福回想性的读书转发了有些之下文章
在运用 Java 的开源项目 JeeSite 时,养成了一个不佳的习于旧贯,习贯给每张表都增加create_by、create_date、update_by、update_date、remarks 和 del_flag 这么多少个字段。假诺每张表都有那多少个字段,那么对每张表举行 insert 时都会对上述的字段举办设置,对每张表进行 update 时都会对里面一些字段进展翻新,对每条记下实行 delete 时都其实是对 del_flag 字段进展置位。重复操作超级多,一些操作方法被涂改。那么,当时将在自定义三个友好的 Model 来作为项指标 基类 了,那个 Model 就负责干上面笔者说的这个事情了。
要测量检验数据库是或不是健康连接,最直接的点子便是在现阶段调整器中实例化数据表,然后采用dump 函数输出,查看数据库的链接状态。代码:
CUENCORED知识之生龙活虎 C 创设(create)
public function testdb(){ $obj=M("User"); dump($obj); }
名词解析:
1 CURD:意味着数据库多个基本操作:创立:create,更新:update,读取:read,删除:delete
自定义叁个 Model
当时浏览器输出:
2 模型对象:即数据对象,你项目里每叁个Model类文件都会对应着一个数据表(或许视图),模型与数码表存在后生可畏种酷炫关系。TP约定了命名要依照一定的职业,假如不符合,则需求依据情状开展额外的相应设置。举个例子Model类的tableName属性
自定义三个 Model,Model 中最少重新 TP 提供的 Model 中的 add、save、delete 和 select 方法。
在第四节时,曾略为涉嫌Model类文件命名,今后再回看一下那部分的内容:
咱俩前边在数据库中,已创建了二个think_form数据库表,而且在陈设文件config.php中,我们定义了数据表的前缀是think_,
模型类(Model卡塔尔国文件的命名准绳是:
定义代码如下:
object(Model)#5 (20) { ["_extModel:private"] => NULL ["db:protected"] => object(DbMysql)#7 (18) { ["dbType:protected"] => string(5) "MYSQL" ["autoFree:protected"] => bool(false) ["model:protected"] => string(7) "_think_" ["pconnect:protected"] => bool(false) ["queryStr:protected"] => string(28) "SHOW COLUMNS FROM `tpk_user`" ["modelSql:protected"] => array(1) { ["user"] => string(28) "SHOW COLUMNS FROM `tpk_user`" } ["lastInsID:protected"] => NULL ["numRows:protected"] => int(2) ["numCols:protected"] => int(0) ["transTimes:protected"] => int(0) ["error:protected"] => string(0) "" ["linkID:protected"] => array(1) { [0] => resource(27) of type (mysql link) } ["_linkID:protected"] => resource(27) of type (mysql link) ["queryID:protected"] => resource(28) of type (mysql result) ["connected:protected"] => bool(true) ["comparison:protected"] => array(10) { ["eq"] => string(1) "=" ["neq"] => string(2) "<>" ["gt"] => string(1) ">" ["egt"] => string(2) ">=" ["lt"] => string(1) "<" ["elt"] => string(2) "<=" ["notlike"] => string(8) "NOT LIKE" ["like"] => string(4) "LIKE" ["in"] => string(2) "IN" ["notin"] => string(6) "NOT IN" } ["selectSql:protected"] => string(96) "SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%" ["bind:protected"] => array(0) { } } ["pk:protected"] => string(2) "id" ["tablePrefix:protected"] => string(4) "tpk_" ["name:protected"] => string(4) "user" ["dbName:protected"] => string(0) "" ["connection:protected"] => string(0) "" ["tableName:protected"] => string(0) "" ["trueTableName:protected"] => string(8) "tpk_user" ["error:protected"] => string(0) "" ["fields:protected"] => array(5) { [0] => string(2) "id" [1] => string(8) "username" ["_autoinc"] => bool(true) ["_pk"] => string(2) "id" ["_type"] => array(2) { ["id"] => string(7) "int(11)" ["username"] => string(11) "varchar(20)" } } ["data:protected"] => array(0) { } ["options:protected"] => array(0) { } ["_validate:protected"] => array(0) { } ["_auto:protected"] => array(0) { } ["_map:protected"] => array(0) { } ["_scope:protected"] => array(0) { } ["autoCheckFields:protected"] => bool(true) ["patchValidate:protected"] => bool(false) ["methods:protected"] => array(13) { [0] => string(5) "table" [1] => string(5) "order" [2] => string(5) "alias" [3] => string(6) "having" [4] => string(5) "group" [5] => string(4) "lock" [6] => string(8) "distinct" [7] => string(4) "auto" [8] => string(6) "filter" [9] => string(8) "validate" [10] => string(6) "result" [11] => string(4) "bind" [12] => string(5) "token" } }
不包涵前缀的数据库表表名还要首字母大写 Model.class.php
1 <?php
2 namespace AdminModel;
3 use ThinkModel;
4
5 /**
6 * 项目中其他 Model 类的基类
7 * 该类继承自 TP 提供的基类 Model
8 */
9 class BaseModel extends Model {
10
11 /**
12 * 继承基类 Model 的 add 方法
13 * 自动插入 id create_by create_date update_by update_date del_flag
14 */
15 public function add($data='',$options=array(),$replace=false) {
16
17 $data["id"] = $this->getUuid();
18 $data["create_by"] = "";
19 $data["create_date"] = date("Y-m-d H:i:s");
20 $data["update_by"] = "";
21 $data["update_date"] = date("Y-m-d H:i:s");
22 $data["del_flag"] = '0';
23
24 return parent::add($data, $options, $replace);
25 }
26
27 /**
28 * 获得 未删除 的所有数据
29 * 记录是否被删除通过 del_flag 字段来进行确定
30 */
31 public function select($options=array()) {
32 $map["del_flag"] = 0;
33 $this->where($map);
34
35 return parent::select($options);
36 }
37
38 /**
39 * 获取 全部 的所有数据
40 */
41 public function selectAll($options=array()) {
42 return parent::select($options);
43 }
44
45 /**
46 * 更新数据
47 * 更新数据时,要更新 update_by update_date 两个字段
48 */
49 public function save($data='',$options=array()) {
50 $data["update_by"] = "";
51 $data["update_date"] = date("Y-m-d H:i:s");
52
53 return parent::save($data, $options);
54 }
55
56 /**
57 * 删除也是更新
58 * 设置 删除 标志位即可
59 */
60 public function delete($data='',$options=array()) {
61 $data["del_flag"] = 1;
62
63 return parent::save($data, $options);
64 }
故而从前大家为think_form数据表在Myapp/Lib/Model目录下树立三个文件FormModel.class.php
那样,我们的 BaseModel 就定义好了,今后项目中的 Model 就不再接续 TP 的 Model 类了,而是继续大家自定义的 BaseModel 了。
若无提醒错误即为成功。
模型类的特出命名还足以智能识别驼峰式的表命名,假使我们有个是附近think_new_table那样的表
能够命名叫NewTableModel.class.php。私下认可配置便能够智能识别自动对应think_new_table表,由此不要改良配置。
M("User") 就是模型映射,M 函数等于 new Model() ,Model 类是模型的基类,也是数据库操作的基类, "User" 是此类的贰个成员属性,表示模型名称,模型名称与数据库中的数据表进行映射。注意:User "U" 要大写,数据库中那时应当留存一张 user 表,系统会依据布置文件中的设置给 user 表增添前缀,例如tpk_user。假设无需为表加多前缀,将模型名称首字母改为小写,比如M("user")。
支付进程中,只要轻易地定义好与数据表对应的模子类(xxxModel.class.php卡塔尔国,就能够张开对数码操作了。
怎么让那个模型支撑电动验证,自动填充,自动过滤那几个文化,在底下涉及届期会作相应疏解。
后续大家定义的基类
貌似的话,在表中添增加少都以透过表单来树立,为了更加直观地读书CUEscortD中的C,咱们接下去创建个表单来打开加多数据的操作。
事情发生前我们已在Myapp/Lib/Model/下创建好FormModel.class.php类----模型(M)
与此同期也在Myapp/Lib/Action/下增多了三个Index应用模块和写下了一个index操作----调控器(C卡塔尔
并且在Tpl目录下建设布局了与之对应的沙盘模拟经营目录Index及index.html模板文件 -------视图(V卡塔尔
MVC格局的支出已反映了出去。
tdweb曾轻便地富含了TP中那三者的涉及,
世袭的 BaseModel 的点子和世袭 Model 的点子是千篇大器晚成律的,只是利用 use 引进命名空间到当前效应域时的内需改进为大家的命名空间,并非再去采纳 TP 提供的命名空间。代码如下:
2.自定义模型
C的功用,正是从M中获得数据到V,
1 <?php
2 namespace AdminModel;
3 use AdminModelBaseModel;
4
5 class TrunkModel extends BaseModel {
D 函数用于连忙实例化自定义模型,能够展开复杂的数据库操作,举例数据印证、数据缓存、数据加工等。自定义模型寄放在 Lib/Model 目录下,举例为多少表 tpk_article 数据表建模映射,则须求创制 阿特icleModel.class.php,然后接收 D 函数实行实例化,ArticleModel 模型将与 tpk_article 表举办映射。
选择TP以表单提交数据到库,流程和你所驾驭的表单提交未有何分别,只是TP简化了数额操作的管理进程。
大家在实操中体味一下。
先来看看我们所定义的多少表form的字段:
use 引入的命名空间是 AdminModelBaseModel ,因为大家定义的 BaseModel 的命名空间是 AdminModel,因为这里的 TrunkModel 和 BaseModel 在贰个命名空间下,省去 use 也是足以的。
例:使用 select() 输出 tpk_article 表的数据 ( select() 方法用于列出具备相符条件的数据 ) :
- 'id',//自动编号
- 'title',//标题
- 'content',//内容
- 'create_time',//创造时间
- 'update_time'//更新时间
- 'email',//邮箱
- 'status',//状态
class IndexAction extends Action { public function article(){ $obj=D("Article"); $rows=$obj->select(); dump($rows); } }
复制代码
那样,在大家用 D 方法实例化 TrunkModel 的对象后,使用 add 方法插入数据时,就能够先调用 BaseModel 中的 add 方法了,那样我们每张表皆有的 create_by 等豆蔻梢头各种字段就都会自行获取了。
浏览器输出:
其中的create_time字段是为了记录数据插入的年月,大家能够运用TP的多寡自动填充来管理。
在Model类定义 $_auto 属性,能够实现多少自动处理效果,用来管理私下认可值和任何 onclick="tagshow(event)">系统写入字段。
瞩目1:该活动填写只怕会覆盖表单提交项目。其目标是为着防卫表单违规提交字段。
留意2:要动用Model类的create方法创设数量对象的时候才会自行举办表单数据管理。
array(6) { [0] => array(7) { ["id"] => string(1) "1" ["title"] => string(4) "test" ["content"] => string(12) "test_content" ["category"] => string(13) "test_category" ["area"] => string(6) "北京" ["add_user"] => string(5) "admin" ["add_time"] => string(19) "2014-11-20 23:03:44" } [1] => array(7) { ["id"] => string(1) "2" ["title"] => string(12) "吼吼吼吼" ["content"] => string(18) "任溶溶柔然人" ["category"] => string(14) "test_category2" ["area"] => string(6) "河北" ["add_user"] => string(5) "admin" ["add_time"] => string(19) "2014-11-22 15:16:12" } [2] => array(7) { ["id"] => string(1) "4" ["title"] => string(7) "test2_m" ["content"] => string(4) "haha" ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => string(19) "2014-11-22 11:44:26" } [3] => array(7) { ["id"] => string(1) "5" ["title"] => string(2) "22" ["content"] => NULL ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => string(19) "2014-11-22 12:40:58" } [4] => array(7) { ["id"] => string(1) "6" ["title"] => string(1) "1" ["content"] => string(1) "2" ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => NULL } [5] => array(7) { ["id"] => string(1) "7" ["title"] => string(6) "lalala" ["content"] => string(6) "hohoho" ["category"] => string(0) "" ["area"] => string(6) "北京" ["add_user"] => NULL ["add_time"] => NULL } }
1 打开Myapp/Lib/Model/FormModel.class.php文件,改正代码为
- <?php
- class FormModel extends Model {
- // 自动填写设置
- protected $_auto = array(
- array('status','1','ADD'),
- array('create_time','time','ADD','function'),
- );
- }
- ?>
代码知识要点:
Model类的$_auto属性由三个填充因子组成的数组,填充因子定义格式:
例2:让 tpk_article 表的内容据他们说客商所在的所在展现本地的新闻:
array(填充字段,填充内容,填充条件,附加法规)
ArticleModel.class.php:
填充字段:便是索要开展拍卖的表单字段,那么些字段并不一定借使数据库表中的字段,对于表单内的扶助检查测试字段例如重复密码和验证码也能够拍卖。
填充条件:ADD | UPDATE | ALL(注意,此是1.5版本表达,1.6已改为1 2
3,后续教程有表明)
当为ADD时,会在增加生产数量多少时自动填充,那是暗中认可的管理格局
当为UPDATE时,在更新数据的时候会自行填写
当为ALL时,全数景况下都会进展活动填写
<?php class ArticleModel extends Model{ public function article(){ $rows=$this->where("area='{$this->checkUserArea()}'")->select(); return $rows; } protected function checkUserArea(){ return "北京"; }
叠合法则:外加法规是照准填充内容来说,表示该内容填充的法门,包蕴function,callback,田野先生,string
对此田野使用任何字段实行填空和string直接标示字符串作为值实行填写很好掌握。举个例子地点
调控器代码:
- array('status','1','ADD'),
IndexAction.class.php:
复制代码
<?php class IndexAction extends Action { $obj=D("Article"); $rows=$obj->article(); $this->assign("list",$rows); $this->display();
即使将气象status字段的值直接以1填充.
何况视图代码:
上面主要说说function与callback那五个附加准绳。
TPL/Index/article.html:
- protected $_auto = array(
- array('create_time','time','ADD','function'),
- );
<!DOCTYPE html> <html> <body> <volist name="list" id="vo"> <li><{$vo.title}> - <{$vo.area}> - <{$vo.content}></li> </volist> </body> </html>
上面create_time代表了要管理的字段,填充内容是time,附加准则是function使用函数,填充条件是ADD新添时管理,那么整行代码表示对create_time字段在增加产能的时候使time函数作为该字段的值实行机动填写。
再看四个function作为附加法则的例证
附:数据表 tpk_article 的表架构为:
- protected $_auto = array(
- array('password','md5','ADD','function'),
- );
当使用function作为附加准则时,第三个填充内容就表示了那一个因子是二个函数名称,该函数的参数就是表示填充字段的值,比如password的值是123456,则上面的代码会先将以此值使用函数md5('123456'),那样管理后再插入到数据表中去。
对于function(函数卡塔尔国和callback(回调方法卡塔 尔(英语:State of Qatar)理论是均等的,只可是一个是表示填充内容所写的是函数名,另三个是象征填充内容是类中的方法名。函数能够是PHP5内置函数或你自个儿所写的函数。而callback是近来模型类所能调用的一个艺术。 至于数据填充方面包车型地铁详细资料,请参见官方使用手册
《ThinkPHP数据操作指南》
小结:自定义模型映射,二个模型对应八个数据表,全部增加和删除改查都在模型类中成就。M 实例化的参数是数据库的表名,D 实例化的是温和在 model 文件夹下创立的模子文件。
2 展开Myapp/Tpl/default/Index/index.html文件,大家改正代码将form写进去
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <html>
- <head>
- <title>{$title}</title>
- </head>
- <body>
- <form action="__URL__/add" method="post" name="formname" id="formname">
- <p>
- <label for="title">标题:</label>
- <input name="title" type="text" id="title" />
- </p>
- <p>
- <label for="email">邮箱:</label>
- <input name="email" type="text" id="email" />
- </p>
- <p><label for="content">内容:</label></p>
- <p>
- <textarea name="content" rows="5" cols="25" id="content" ></textarea>
- </p>
- <p><input type="submit" value="提交" /></p>
- </form>
</body>
</html>
3.create 方法
在上边代码中,大家简要地建了七个form表单,并将标题统一运用叁个模板变量{$title}。
action提交到的管理地点是__URL__/add,其中__URL__是叁个常量定义,表示近来模块地址,TP模板引擎会活动将那句解释为/index.php/Index/add,司空眼惯的模版使用的常量有
TP 对数码的插入和换代都做了高度封装:提供了 create() 方法用于创建数量对象。
__ROOT__ 网址根目录地址
__APP__ 当前项目(入口文件卡塔 尔(英语:State of Qatar)地址
__URL__ 当前模块地址
__ACTION__ 当前操作地址
__SELF__ 当前 URL 地址
概念:数据对象 —— 数据字段与数据表之间的关系,数据会被映射为类成员,再与数码表映射,最后达成多少的插入或更新。
3 设置模板变量 {$title} ,扩大add操作方法
create() 方法是贯穿操作、CUGL450D 操作的集合 ( 包罗数据创制、数据印证、表单验证、自动完毕等 )。
开辟Myapp/Lib/Action/IndexAction.class.php文件,改进代码如下
cerate() 的数据源由 POST 表单提供,比如表单中有 username 表单成分,则该因素会被电动映射为多少表中的 username 字段。数据对象创制作而成功以往,对象被存放在于内部存款和储蓄器中。
- <?php
- class IndexAction extends Action{
- public function index() {
- $this->assign('title','增多数据');//这里设置了模版变量{$title}
- $this->display();
- }
- // 管理表单数据的主意
- function add() {
- $Form = D("Form");
- if($Form->create()) {
- $Form->add();
- $this->redirect();
- }else{
- header("Content-Type:text/html; charset=utf-8");
- exit($Form->getError().' [ <A >返 回</A> ]');
- }
- }
- }//类定义 end
- ?>
例:加多数量
代码知识要点:
模板变量赋值前边的章节已介绍过。这里就不啰嗦了。
控制器:IndexAction,动作:add_article,代码:
大家来会见add方法的代码。
$Form = D("Form");
那边运用了TP的性情单字母函数D,是操作数据库时最常用的TP函数,表示实例化Form对象,
即$Form = new FormModel();
D函数的现实性代码能够查阅ThinkPHP目录内的common/function.php中的片段,
它会自行引进Model类,并认清以前假使实例化过那个Model,就不再实例化,若然该Model子虚乌有,就能抛出拾叁分错误,此外,D能够跨连串访谈Model,权且忽视。
IndexAction.class.php:
$Form->create()
选用Model类的Create方法创立三个Form对象,失利会再次来到false。
<?php class IndexAction extends Action { Public function add_article(){ $this->display(); } }
$Form->add(); //add方法会将表单数据开展写入
$this->redirect(); //实行跳转
有如此轻便几行代码,便完毕了对数码插入的拍卖。
视图: Tpl/Index/add_article.html:
<!DOCTYPE html> <html> <body> <form method="post" action="__URL__/add"> <input type="text" name="title" placeholder="标题"><br><br> <textarea name="content" id="content" placeholder="内容"></textarea><br><br> <input type="submit" name="submit" value="提交"> </form> </body> </html>
__URL__/add 代表近日调节器的 add 动作。
add 动作代码:
<?php class IndexAction extends Action { public function add(){ //表单处理 $articleObj = M('Article'); $articleObj->create(); $articleObj->add_time = date("Y-m-d H:i:s",time()); if($articleObj->add()){ $this->success("数据添加成功"); }else{ $this->error("数据添加失败"); } }
事例截至。
4.模子属性( Model )
_map 属性:字段映射
为了制止前台表单成分与数据库字段名相近而使数据库字段暴光,能够改善前台表单成分的 name,同有的时候候在 Model 中运用 _map 属性。代码:
视图:Tpl/Index/add_article.html:
<!DOCTYPE html> <html> <body> <form method="post" action="__URL__/add"> <input type="text" name="subject" placeholder="标题"><br><br> <textarea name="textEdit" id="content" placeholder="内容"></textarea><br><br> <input type="submit" name="submit" value="提交"> </form> </body> </html>
模型:ArticleModel.class.php:
<?php class ArticleModel extends Model{ //使用_map属性(字段映射)将表单元素映射为相应表字段 protected $_map = array( "subject"=>"title", "textEdit"=>"content" ); }
控制器:IndexAction.class.php:
<?php class IndexAction extends Action { $articleObj = D("Article"); $articleObj->create(); $articleObj->add_time = date("Y-m-d H:i:s",time()); if($articleObj->add()){ $this->success("数据添加成功"); }else{ $this->error("数据添加失败"); } }
事例结束。
二、根底模型
1.连贯操作
贯通方法除了 select() 方法外,其余的贯通方法不区分前后相继。
例:
$rows=$obj->where("add_user='dee'")->order("add_time desc")->limit(10)->select();
2.CURD
① 成立数量 add()
<?php class IndexAction extends Action { public function post(){ $articleObj = D("Article"); $data['title'] = $_POST['subject']; $data['content'] = $_POST['textEdit']; $data['add_time'] = date("Y-m-d H:i:s",time()); if($articleObj->add($data)){ $this->success("数据添加成功"); }else{ $this->error("数据添加失败"); } } }
另二个事例:
<?php class IndexAction extends Action { public function post(){ $articleObj = D("Article"); $data['title'] = $_POST['subject']; $data['content'] = $_POST['textEdit']; $data['add_time'] = date("Y-m-d H:i:s",time()); if($articleObj->data($data)->add()){ $this->success("数据添加成功"); }else{ $this->error("数据添加失败"); } } }
② 更新数据 save()
<?php class IndexAction extends Action { public function post2(){ $articleObj = M("Article"); $data['id'] = 2; $data['title'] = $_POST['subject']; $data['content'] = $_POST['textEdit']; $data['area'] = '河北'; $data['add_time'] = date("Y-m-d H:i:s",time()); if($articleObj->save($data)){ $this->success("数据修改成功"); }else{ $this->error("数据修改失败"); } } }
③ 读取数据 select 和 getFiled
getField 例子:
<?php class IndexAction extends Action { public function post3(){ $articleObj = M("Article"); if($articleObj->where("id=3")->setField("content","{$_POST['subject']}")){ $this->success("数据修改成功"); }else{ $this->error("数据修改失败"); } } }
④ 删除数据 delete
<?php class IndexAction extends Action { public function delete(){ $articleObj = M("Article"); if($articleObj->where("id=".$_GET['id'])->delete()){ $this->success("数据删除成功"); }else{ $this->error("数据删除失败"); } } }
3.询问语言
例子:
<?php class IndexAction extends Action { public function archives(){ $obj = M("Archives"); // $data['writer'] = array("eq","网络营销中心"); // $data['title'] = array("like","精诚%"); $data['id'] = array("lt","100"); $rows=$obj->where($data)->select(); $count=$obj->where($data)->count(); $tb=C("DB_PREFIX"); $this->assign("list",$rows); $this->assign("count",$count); $this->assign("tb",$tb); $this->display("Article"); } public function archives2(){ $obj = M("Archives"); $data['id'] = array(array("lt","1034"),array("GT","1029"),"and"); $rows=$obj->where($data)->select(); $this->assign("list",$rows); $this->display("Article"); } }
可以在调控器中央银行使 echo $obj->getLastSql(); 查看转换后的 SQL 语句。
参谋资料:《PHP MVC 开荒实战》
本文由大富豪棋牌游戏手机版发布,转载请注明来源:数据库操作之数据表模型和基础模型,ThinkPHP学习