工作中,有是需要连接多个数据库,thinkphp5中也可以连接多个数据库,不影响主数据库,在application/config.php中加入配置,主数据库配置文件 database.php不需要动//数据库配置2'db_config2'=>[//数据库类型'type'=>'mysql',//数据库连接DSN配置'dsn'=>'',//服务器地址'hostname'=>'127.0.0.1',//数据库名'database'=>'tp5_Db2',//数据库用户名'username'=>'root',//数据库密码'password'=>'root',//数据库连接端口'hostport'=>'',//数据库连接参数'params'=>[],//数据库编码默认采用utf8'charset'=>'utf8',//数据库表前缀'prefix'=>'hf_',],调用方法:$res=Db::connect(config('db_config2'))->name('tp_shop')->order('iddesc')->paginate(22);$this->assign('res',$res);
查询一个数据使用://table方法必须指定完整的数据表名Db::table('think_user')->where('id',1)->find();查询某个字段的值可以用//返回某个字段的值Db::table('think_user')->where('id',1)->value('name');查询某一列的值可以用//返回数组Db::table('think_user')->where('status',1)->column('name');//指定索引Db::table('think_user')->where('status',1)->column('name','id');添加一条数据//使用Db类的insert方法向数据库提交数据$data=['foo'=>'bar','bar'=>'foo'];Db::table('think_user')->insert($data);//如果你在database.PHP配置文件中配置了数据库前缀(prefix),那么可以直接使用Db类的name方法提交数据Db::name('user')->insert($data);添加多条数据//添加多条数据直接向Db类的insertAll方法传入需要添加的数据即可$data=[['foo'=>'bar','bar'=>'foo'],['foo'=>'bar1','bar'=>'foo1'],['foo'=>'bar2','bar'=>'foo2']];Db::name('user')->insertAll($data);更新数据表中的数据Db::table('think_user')->where('id',1)->update(['name'=>'thinkphp']);如果数据中包含主键,可以直接使用:Db::table('think_user')->update(['name'=>'thinkphp','id'=>1]);更新某个字段的值:Db::table('think_user')->where('id',1)->setField('name','thinkphp');删除数据表中的数据//根据主键删除Db::table('think_user')->delete(1);Db::table('think_user')->delete([1,2,3]);//条件删除Db::table('think_user')->where('id',1)->delete();Db::table('think_user')->where('id','<',10)->delete();where语句Db::table('think_user')->where('id','>',1)->where('name','thinkphp')->select();最简单的数组查询方式如下:$map['name']='thinkphp';$map['status']=1;//把查询条件传入查询方法Db::table('think_user')->where($map)->select();表达式查询可以在数组条件中使用查询表达式,例如:$map['id']=['>',1];$map['mail']=['like','%thinkphp@qq.com%'];Db::table('think_user')->where($map)->select();字符串条件使用字符串条件直接查询和操作,例如:Db::table('think_user')->where('type=1ANDstatus=1')->select();aliasalias用于设置当前数据表的别名,便于使用其他的连贯操作例如join方法等。Db::table('think_user')->alias('a')->join('__DEPT__b','b.user_id=a.id')->select();最终生成的sql语句类似于:SELECT*FROMthink_useraINNERJOINthink_deptbONb.user_id=a.idv5.0.2+版本开始,可以传入数组批量设置数据表以及别名,例如:Db::table('think_user')->alias(['think_user'=>'user','think_dept'=>'dept'])->join('think_dept','dept.user_id=user.id')->select();最终生成的SQL语句类似于:SELECT*FROMthink_useruserINNERJOINthink_deptdeptONdept.user_id=user.id用于查询指定字段field在查询操作中field方法是使用最频繁的。Db::table('think_user')->field('id,title,content')->select();可以给某个字段设置别名,例如:Db::table('think_user')->field('id,nicknameasname')->select();可以在field方法中直接使用函数,例如:Db::table('think_user')->field('id,SUM(score)')->select();字段排除如果我希望获取排除数据表中的content字段(文本字段的值非常耗内存)之外的所有字段值,我们就可以使用field方法的排除功能,例如下面的方式就可以实现所说的功能:Db::table('think_user')->field('content',true)->select();则表示获取除了content之外的所有字段,要排除更多的字段也可以:Db::table('think_user')->field('user_id,content',true)->select();//或者用Db::table('think_user')->field(['user_id','content'],true)->select();order方法属于模型的连贯操作方法之一,用于对操作的结果排序。Db::table('think_user')->where('status=1')->order('iddesc')->limit(5)->select();注意:连贯操作方法没有顺序,可以在select方法调用之前随便改变调用顺序。支持对多个字段的排序,例如:Db::table('think_user')->where('status=1')->order('iddesc,status')->limit(5)->select();如果没有指定desc或者asc排序规则的话,默认为asc。如果你的字段和mysql关键字有冲突,那么建议采用数组方式调用,例如:Db::table('think_user')->where('status=1')->order(['order','id'=>'desc'])->limit(5)->select();limit方法也是模型类的连贯操作方法之一,主要用于指定查询和操作的数量,特别在分页查询的时候使用较多。thinkphp的limit方法可以兼容所有的数据库驱动类的。限制结果数量例如获取满足要求的10个用户,如下调用即可:Db::table('think_user')->where('status=1')->field('id,name')->limit(10)->select();limit方法也可以用于写操作,例如更新满足要求的3条数据:Db::table('think_user')->where('score=100')->limit(3)->update(['level'=>'A']);分页查询用于文章分页查询是limit方法比较常用的场合,例如:Db::table('think_article')->limit('10,25')->select();表示查询文章数据,从第10行开始的25条数据(可能还取决于where条件和order排序的影响这个暂且不提)。你也可以这样使用,作用是一样的:Db::table('think_article')->limit(10,25)->select();对于大数据表,尽量使用limit限制查询结果,否则会导致很大的内存开销和性能问题。page利用扩展类库中的分页类Page可以自动计算出每个分页的limit参数,但是如果要自己写就比较费力了,如果用page方法来写则简单多了,例如://查询第一页数据Db::table('think_article')->page('1,10')->select();//查询第二页数据Db::table('think_article')->page('2,10')->select();显而易见的是,使用page方法你不需要计算每个分页数据的起始位置,page方法内部会自动计算。和limit方法一样,page方法也支持2个参数的写法,例如:Db::table('think_article')->page(1,10)->select();//和下面的用法等效Db::table('think_article')->page('1,10')->select();page方法还可以和limit方法配合使用,例如:Db::table('think_article')->limit(25)->page(3)->select();当page方法只有一个值传入的时候,表示第几页,而limit方法则用于设置每页显示的数量,也就是说上面的写法等同于:Db::table('think_article')->page('3,25')->select();groupGROUP方法也是连贯操作方法之一,通常用于结合合计函数,根据一个或多个列对结果集进行分组。group方法只有一个参数,并且只能使用字符串。例如,我们都查询结果按照用户id进行分组统计:Db::table('think_user')->field('user_id,username,max(score)')->group('user_id')->select();生成的sql语句是:SELECTuser_id,username,max(score)FROMthink_scoreGROUPBYuser_id也支持对多个字段进行分组,例如:Db::table('think_user')->field('user_id,test_time,username,max(score)')->group('user_id,test_time')->select();生成的SQL语句是:SELECTuser_id,test_time,username,max(score)FROMthink_scoreGROUPBYuser_id,test_timehavingHAVING方法也是连贯操作之一,用于配合group方法完成从分组的结果中筛选(通常是聚合条件)数据。having方法只有一个参数,并且只能使用字符串,例如:Db::table('think_user')->field('username,max(score)')->group('user_id')->having('count(test_time)>3')->select();生成的sql语句是:SELECTusername,max(score)FROMthink_scoreGROUPBYuser_idHAVINGcount(test_time)>3join查询Db::table('think_artist')->alias('a')->join('think_workw','a.id=w.artist_id')->join('think_cardc','a.card_id=c.id')->select();Db::table('think_artist')->alias('a')->join('__WORK__w','a.id=w.artist_id')->join('__CARD__c','a.card_id=c.id')->select();$join=[['think_workw','a.id=w.artist_id'],['think_cardc','a.card_id=c.id'],];Db::table('think_user')->alias('a')->join($join)->select();以上三种写法的效果一样,__WORK__和__CARD__在最终解析的时候会转换为think_work和think_card。注意:'_表名_'这种方式中间的表名需要用大写如果不想使用别名,后面的条件就要使用表全名,可以使用下面这种方式Db::table('think_user')->join('__WORK__','__ARTIST__.id=__WORK__.artist_id')->select();UNION操作用于合并两个或多个SELECT语句的结果集。Db::field('name')->table('think_user_0')->union('SELECTnameFROMthink_user_1')->union('SELECTnameFROMthink_user_2')->select();Db::field('name')->table('think_user_0')->union(['SELECTnameFROMthink_user_1','SELECTnameFROMthink_user_2'])->select();支持UNIONALL操作,例如:Db::field('name')->table('think_user_0')->union('SELECTnameFROMthink_user_1',true)->union('SELECTnameFROMthink_user_2',true)->select();或者Db::field('name')->table('think_user_0')->union(['SELECTnameFROMthink_user_1','SELECTnameFROMthink_user_2'],true)->select();每个union方法相当于一个独立的SELECT语句。注意:UNION内部的SELECT语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条SELECT语句中的列的顺序必须相同。distinctDISTINCT方法用于返回唯一不同的值。以下代码会返回user_login字段不同的数据Db::table('think_user')->distinct(true)->field('user_login')->select();生成的sql语句是:SELECTDISTINCTuser_loginFROMthink_user返回以下数组array(2){[0]=>array(1){["user_login"]=>string(7)"chunice"}[1]=>array(1){["user_login"]=>string(5)"admin"}}distinct方法的参数是一个布尔值。lockLock方法是用于数据库的锁机制,如果在查询或者执行操作的时候使用:lock(true);就会自动在生成的sql语句最后加上FORUPDATE或者FORUPDATENOWAIT(oracle数据库)。cachecache方法用于查询缓存操作,也是连贯操作方法之一。cache可以用于select、find、value和column方法,以及其衍生方法,使用cache方法后,在缓存有效期之内不会再次进行数据库查询操作,而是直接获取缓存中的数据,关于数据缓存的类型和设置可以参考缓存部分。下面举例说明,例如,我们对find方法使用cache方法如下:Db::table('think_user')->where('id=5')->cache(true)->find();第一次查询结果会被缓存,第二次查询相同的数据的时候就会直接返回缓存中的内容,而不需要再次进行数据库查询操作。默认情况下,缓存有效期是由默认的缓存配置参数决定的,但cache方法可以单独指定,例如:Db::table('think_user')->cache(true,60)->find();//或者使用下面的方式是等效的Db::table('think_user')->cache(60)->find();表示对查询结果的缓存有效期60秒。当你删除或者更新数据的时候,可以使用cache方法手动更新(清除)缓存,例如:Db::table('think_user')->cache('user_data')->select([1,3,5]);Db::table('think_user')->cache('user_data')->update(['id'=>1,'name'=>'thinkphp']);Db::table('think_user')->cache('user_data')->select([1,5]);最后查询的数据不会受第一条查询缓存的影响,确保查询和更新或者删除使用相同的缓存标识才能自动清除缓存。如果使用find方法并且使用主键查询的情况,不需要指定缓存标识,会自动清理缓存,例如:Db::table('think_user')->cache(true)->find(1);Db::table('think_user')->update(['id'=>1,'name'=>'thinkphp']);Db::table('think_user')->cache(true)->find(1);最后查询的数据会是更新后的数据。commentCOMMENT方法用于在生成的sql语句中添加注释内容,例如:Db::table('think_score')->comment('查询考试前十名分数')->field('username,score')->limit(10)->order('scoredesc')->select();最终生成的SQL语句是:SELECTusername,scoreFROMthink_scoreORDERBYscoredescLIMIT10/*查询考试前十名分数*/fetchSqlfetchSql用于直接返回SQL而不是执行查询,适用于任何的CURD操作方法。例如:$result=Db::table('think_user')->fetchSql(true)->find(1);输出result结果为:SELECT*FROMthink_userwhereid=1forceforce方法用于数据集的强制索引操作,例如:Db::table('think_user')->force('user')->select();对查询强制使用user索引,user必须是数据表实际创建的索引名称。bindbind方法用于手动参数绑定,大多数情况,无需进行手动绑定,系统会在查询和写入数据的时候自动使用参数绑定。bind方法用法如下://用于查询Db::table('think_user')->where('id',':id')->where('name',':name')->bind(['id'=>[10,\PDO::PARAM_INT],'name'=>'thinkphp'])->select();//用于写入Db::table('think_user')->bind(['id'=>[10,\PDO::PARAM_INT],'email'=>'thinkphp@qq.com','name'=>'thinkphp'])->where('id',':id')->update(['name'=>':name','email'=>':email');partitionpartition方法用于是数据库水平分表partition($data,$field,$rule);//$data分表字段的数据//$field分表字段的名称//$rule分表规则注意:不要使用任何SQL语句中会出现的关键字当表名、字段名,例如order等。会导致数据模型拼装SQL语句语法错误。partition方法用法如下://用于写入$data=['user_id'=>110,'user_name'=>'think'];$rule=['type'=>'mod',//分表方式'num'=>10//分表数量];Db::name('log')->partition(['user_id'=>110],"user_id",$rule)->insert($data);//用于查询Db::name('log')->partition(['user_id'=>110],"user_id",$rule)->where(['user_id'=>110])->select();strictstrict方法用于设置是否严格检查字段名,用法如下://关闭字段严格检查Db::name('user')->strict(false)->insert($data);注意,系统默认值是由数据库配置参数fields_strict决定,因此修改数据库配置参数可以进行全局的严格检查配置,如下://关闭严格检查字段是否存在'fields_strict'=>false,如果开启字段严格检查的话,在更新和写入数据库的时候,一旦存在非数据表字段的值,则会抛出异常。failExceptionfailException设置查询数据为空时是否需要抛出异常,如果不传入任何参数,默认为开启,用于select和find方法,例如://数据不存在的话直接抛出异常Db:name('blog')->where(['status'=>1])->failException()->select();//数据不存在返回空数组不抛异常Db:name('blog')->where(['status'=>1])->failException(false)->select();或者可以使用更方便的查空报错//查询多条Db:name('blog')->where(['status'=>1])->selectOrFail();//查询单条Db:name('blog')->where(['status'=>1])->findOrFail();聚合查询count统计数量,参数是要统计的字段名(可选)max获取最大值,参数是要统计的字段名(必须)min获取最小值,参数是要统计的字段名(必须)avg获取平均值,参数是要统计的字段名(必须)sum获取总分,参数是要统计的字段名(必须)获取用户数:Db::table('think_user')->count();//助手函数db('user')->count();或者根据字段统计:Db::table('think_user')->count('id');//助手函数db('user')->count('id');获取用户的最大积分:Db::table('think_user')->max('score');//助手函数db('user')->max('score');获取积分大于0的用户的最小积分:Db::table('think_user')->where('score>0')->min('score');//助手函数db('user')->where('score>0')->min('score');获取用户的平均积分:Db::table('think_user')->avg('score');//助手函数db('user')->avg('score');统计用户的总成绩:Db::table('think_user')->sum('score');//助手函数db('user')->sum('score');时间段查询where方法支持时间比较,例如://大于某个时间where('create_time','>time','2016-1-1');//小于某个时间where('create_time','<=time','2016-1-1');//时间区间查询where('create_time','betweentime',['2015-1-1','2016-1-1']);第三个参数可以传入任何有效的时间表达式,会自动识别你的时间字段类型,支持的时间类型包括timestamps、datetime、date和int。使用whereTime方法whereTime方法提供了日期和时间字段的快捷查询,示例如下://大于某个时间db('user')->whereTime('birthday','>=','1970-10-1')->select();//小于某个时间db('user')->whereTime('birthday','<','2000-10-1')->select();//时间区间查询db('user')->whereTime('birthday','between',['1970-10-1','2000-10-1'])->select();//不在某个时间区间db('user')->whereTime('birthday','notbetween',['1970-10-1','2000-10-1'])->select();时间表达式还提供了更方便的时间表达式查询,例如://获取今天的博客db('blog')->whereTime('create_time','today')->select();//获取昨天的博客db('blog')->whereTime('create_time','yesterday')->select();//获取本周的博客db('blog')->whereTime('create_time','week')->select();//获取上周的博客db('blog')->whereTime('create_time','lastweek')->select();//获取本月的博客db('blog')->whereTime('create_time','month')->select();//获取上月的博客db('blog')->whereTime('create_time','lastmonth')->select();//获取今年的博客db('blog')->whereTime('create_time','year')->select();//获取去年的博客db('blog')->whereTime('create_time','lastyear')->select();如果查询当天、本周、本月和今年的时间,还可以简化为://获取今天的博客db('blog')->whereTime('create_time','d')->select();//获取本周的博客db('blog')->whereTime('create_time','w')->select();//获取本月的博客db('blog')->whereTime('create_time','m')->select();//获取今年的博客db('blog')->whereTime('create_time','y')->select();快捷查询快捷查询方式是一种多字段相同查询条件的简化写法,可以进一步简化查询条件的写法,在多个字段之间用|分割表示OR查询,用&分割表示AND查询,可以实现下面的查询,例如:Db::table('think_user')->where('name|title','like','thinkphp%')->where('create_time&update_time','>',0)->find();生成的查询SQL是:SELECT*FROM`think_user`WHERE(`name`LIKE'thinkphp%'OR`title`LIKE'thinkphp%')AND(`create_time`>0AND`update_time`>0)LIMIT1快捷查询支持所有的查询表达式。区间查询区间查询是一种同一字段多个查询条件的简化写法,例如:Db::table('think_user')->where('name',['like','thinkphp%'],['like','%thinkphp'])->where('id',['>',0],['<>',10],'or')->find();生成的sql语句为:SELECT*FROM`think_user`WHERE(`name`LIKE'thinkphp%'AND`name`LIKE'%thinkphp')AND(`id`>0OR`id`<>10)LIMIT1区间查询的查询条件必须使用数组定义方式,支持所有的查询表达式。下面的查询方式是错误的:Db::table('think_user')->where('name',['like','thinkphp%'],['like','%thinkphp'])->where('id',5,['<>',10],'or')->find();批量查询可以进行多个条件的批量条件查询定义,例如:Db::table('think_user')->where(['name'=>['like','thinkphp%'],'title'=>['like','%thinkphp'],'id'=>['>',0],'status'=>1])->select();生成的SQL语句为:SELECT*FROM`think_user`WHERE`name`LIKE'thinkphp%'AND`title`LIKE'%thinkphp'AND`id`>0AND`status`='1'闭包查询Db::table('think_user')->select(function($query){$query->where('name','thinkphp')->whereOr('id','>',10);});生成的SQL语句为:SELECT*FROM`think_user`WHERE`name`='thinkphp'OR`id`>10使用Query对象查询也可以事先封装Query对象,并传入select方法,例如:$query=new\think\db\Query;$query->name('user')->where('name','like','%think%')->where('id','>',10)->limit(10);Db::select($query);如果使用Query对象的话,select方法之前调用的任何的链式操作都是无效。混合查询可以结合前面提到的所有方式进行混合查询,例如:Db::table('think_user')->where('name',['like','thinkphp%'],['like','%thinkphp'])->where(function($query){$query->where('id',['<',10],['>',100],'or');})->select();生成的SQL语句是:SELECT*FROM`think_user`WHERE(`name`LIKE'thinkphp%'AND`name`LIKE'%thinkphp')AND(`id`<10or`id`>100)字符串条件查询对于一些实在复杂的查询,也可以直接使用原生SQL语句进行查询,例如:Db::table('think_user')->where('id>0ANDnameLIKE"thinkphp%"')->select();为了安全起见,我们可以对字符串查询条件使用参数绑定,例如:Db::table('think_user')->where('id>:idANDnameLIKE:name',['id'=>0,'name'=>'thinkphp%'])->select();V5.0.4+开始,ThinkPHP支持对同一个字段多次调用查询条件,例如:Db::table('think_user')->where('name','like','%think%')->where('name','like','%php%')->where('id','in',[1,5,80,50])->where('id','>',10)->find();原生查询Db类支持原生SQL查询操作,主要包括下面两个方法:query方法query方法用于执行SQL查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同select方法)。使用示例:Db::query("select*fromthink_userwherestatus=1");如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的sql语句是什么。execute方法execute用于更新和写入数据的sql操作,如果数据非法或者查询错误则返回false,否则返回影响的记录数。使用示例:Db::execute("updatethink_usersetname='thinkphp'wherestatus=1");如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。参数绑定支持在原生查询的时候使用参数绑定,包括问号占位符或者命名占位符,例如:Db::query("select*fromthink_userwhereid=?ANDstatus=?",[8,1]);//命名绑定Db::execute("updatethink_usersetname=:namewherestatus=:status",['name'=>'thinkphp','status'=>1]);
以下方法在网站稳定后再生成上传。方法如下:路由缓存生成类库映射文件生成数据表字段缓存开启请求缓存为应用或者模块生成配置缓存文件如何生存路由缓存phpthinkoptimize:route如果你的应用中,定义使用了大量的路由规则,那么博主建议你可以在实际部署完成后,进行生成路由缓存文件操作,因为这样就可以免除你在打开这个应用时候路由注册的开销,从而改善路由的检测效率这里如果没有权限,就会报异常!操作成功以后,你的应用根目录runtime文件夹下就会自动生成一个route.php文件生成类库映射文件phpthinkoptimize:autoload而类库映射文件的操作,它可以提高自动加载的性能操作成功以后,你的应用根目录runtime文件夹下就会自动生成一个classmap.php文件生成数据表字段缓存phpthinkoptimize:schema如果你是希望提高对数据库的查询性能,你可以通过生成字段缓存来减少查询操作成功以后,你的应用根目录runtime文件夹下就创建schema目录,然后在该目录下面按照database.table.php的文件命名生成数据表字段缓存文件。开启请求缓存如果你的数据实时性不是很大,那么你就可以进行开启,在config.php下将request_cache改成true,默认为false状态‘request_cache’=>true,一旦开启后,你的应用性能会有非常大的提高为应用或者模块生成配置缓存文件phpthinkoptimize:config默认生成应用的配置缓存文件,调用后会在runtime目录下面生成init.php文件,生成配置缓存文件后,应用目录下面的config.phpcommon.php以及tags.php不会被加载,被runtime/init.php取代。这里你值得要注意的是,如果你是在本地生成配置缓存时需要把数据库等重要的配置替换成服务器上的配置以后,再进行生成。
前言ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。遵循Apache2开源许可协议发布,意味着你可以免费使用ThinkPHP,甚至允许把你基于ThinkPHP开发的应用开源或商业产品发布/销售。一、ThinkPHP5实现用户登录,文章评论。登录验证,文章评论关联,二、使用步骤1.创建数据表CREATETABLE`user`(`id`int(10)NOTNULLAUTO_INCREMENT,`t_id`int(10)DEFAULTNULL,`name`varchar(30)COLLATEutf8_unicode_ciDEFAULTNULL,`pwd`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`nikename`varchar(30)COLLATEutf8_unicode_ciDEFAULTNULL,`status`enum('0','1')COLLATEutf8_unicode_ciDEFAULTNULLCOMMENT'0异常1正常',`created_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,`updated_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=MyISAMAUTO_INCREMENT=9DEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci;CREATETABLE`comment`(`id`int(10)NOTNULLAUTO_INCREMENT,`u_id`int(10)DEFAULTNULL,`t_id`int(10)DEFAULTNULL,`comment_content`varchar(200)COLLATEutf8_unicode_ciDEFAULTNULL,`created_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,`updated_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=MyISAMAUTO_INCREMENT=3DEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci;CREATETABLE`theme`(`id`int(10)NOTNULLAUTO_INCREMENT,`u_id`int(10)DEFAULTNULL,`c_id`int(10)DEFAULTNULL,`classify`varchar(10)COLLATEutf8_unicode_ciDEFAULTNULL,`title`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`content`textCOLLATEutf8_unicode_ci,`image_url`varchar(100)COLLATEutf8_unicode_ciDEFAULTNULL,`comment_count`int(6)DEFAULTNULL,`created_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,`updated_at`timestampNULLDEFAULTNULLONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=MyISAMAUTO_INCREMENT=3DEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci;2.视图层login:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>站三界导航www.zhansanjie.com</title><!--最新版本的Bootstrap核心CSS文件--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"crossorigin="anonymous"><!--可选的Bootstrap主题文件(一般不用引入)--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"crossorigin="anonymous"><!--最新的Bootstrap核心JavaScript文件--><scriptsrc="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"crossorigin="anonymous"></script></head><body><formaction="get-info"method="post">{:token()}用户名:<inputtype="text"name="name"><br>密码:<inputtype="password"name="pwd"><br>验证码<inputtype="text"name="yzm"><div><imgsrc="{:captcha_src()}"alt="captcha"onclick="this.src='{:captcha_src()}'"/></div><inputtype="submit"value="登录"></form></body></html>list:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>站三界导航www.zhansanjie.com</title><!--最新版本的Bootstrap核心CSS文件--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"crossorigin="anonymous"><!--可选的Bootstrap主题文件(一般不用引入)--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"crossorigin="anonymous"><!--最新的Bootstrap核心JavaScript文件--><scriptsrc="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"crossorigin="anonymous"></script></head><body><h2>今日头条<ahref="/Wx/Users/logout"style="float:right;font-size:14px;margin-top:10px">退出登录</a></h2><div><tableclass="tabletable-hover"><tr><th>标题</th><th></th><th>操作</th></tr>{volistname='list'id='user'}{volistname="user['comment']"id="sub"}<tr><td>{$user.title}<divstyle="font-size:10px;margin-top:10px;color:#9F9F9F">发布时间:{$user.created_at} 类型:{$user.classify} 评论数:{$user.comment_count}</div></td><td><imgsrc="/uploads/{$user.image_url}"alt=""width="60px"height="60px"class="img-circle"></td><td><ahref="\theme\detail?id={$user.id}"style="line-height:50px">详情</a></td></tr>{/volist}{/volist}</table><divstyle="font-size:12px;margin-top:50px;margin-left:10px">共有{$total}条</div></div>{$page|raw}</body></html>detail:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>站三界导航www.zhansanjie.com</title><!--最新版本的Bootstrap核心CSS文件--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"crossorigin="anonymous"><!--可选的Bootstrap主题文件(一般不用引入)--><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"crossorigin="anonymous"><!--最新的Bootstrap核心JavaScript文件--><scriptsrc="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"crossorigin="anonymous"></script></head><body><h2>详情</h2><div><tableclass="tabletable-hover">{volistname='lists'id='data'}{volistname="data['comment']"id="su"}{volistname="data['user']"id="s"}<tr><tdstyle="text-align:center">{$data.title}</td></tr><tr><td>{$data.content}</td></tr><tr><td><inputtype="button"onclick="createInput()"value="评论:"/></td></tr><tr><td>{$s.name}:{$su.comment_content}</td></tr>{/volist}{/volist}{/volist}</table></div><divid="test"></div></body></html><script>functioncreateInput(){document.getElementById("test").innerHTML="<formaction='get-info'method='post'>评论:<inputtype='text'name='comment_content'/><inputtype='submit'value='提交'/></form>";}</script>3.验证器validate:<?phpnamespaceapp\wx\validate;usethink\Validate;classWxsextendsValidate{/***定义验证规则*格式:'字段名'=>['规则1','规则2'...]**@vararray*/protected$rule=['name'=>'require|max:25|token','pwd'=>'require','yzm'=>'require|captcha',];/***定义错误信息*格式:'字段名.规则名'=>'错误信息'**@vararray*/protected$message=['name.require'=>'姓名必填','name.max'=>'姓名最多不能超过25个字符','name.token'=>'token验证','pwd.require'=>'密码必填','yzm.require'=>'验证码必填','yzm.captcha'=>'验证码错误',];}3.模型层User:<?phpnamespaceapp\wx\model;usethink\facade\Session;usethink\Model;classUserextendsModel{//自动写入时间戳字段protected$autoWriteTimestamp='timestamp';//true开启;false关闭//创建时间字段自定义protected$createTime='created_at';//默认create_time//更新时间字段自定义protected$updateTime='updated_at';//默认update_time//设置当前模型对应的完整数据表名称protected$table='user';//用户表多对多关联publicfunctiontheme(){return$this->belongsTo('Theme');}//用户登录publicstaticfunctionlogin($data){$user=self::where('status',1)->where('name',$data['name'])->find();if($user){if($user['pwd']==md5($data['pwd'])){session('name',$user['name']);session('id',$user['id']);return3;//信息正确}else{return2;//密码错误}}else{return1;//用户不存在}}//退出登录publicstaticfunctionlogout(){Session::delete('name');Session::delete(('id'));Session::clear();}}Theme:<?phpnamespaceapp\wx\model;usethink\facade\Cache;usethink\facade\Debug;usethink\Model;classThemeextendsModel{//自动写入时间戳字段protected$autoWriteTimestamp='timestamp';//true开启;false关闭//创建时间字段自定义protected$createTime='created_at';//默认create_time//更新时间字段自定义protected$updateTime='updated_at';//默认update_time//设置当前模型对应的完整数据表名称protected$table='theme';//建立和comment的关联publicfunctioncomment(){return$this->hasMany('Comment','t_id');//hasOne是一对一}//建立和user的关联publicfunctionuser(){return$this->hasMany('User','t_id');//hasMany是一对多}constCACHE_KEY_PREFIX=__CLASS__.'-'.__FILE__.'-id:';publicstaticfunctiongetUserById($id){$cacheKey=self::CACHE_KEY_PREFIX.$id;//Debug::remark('cachekey',$cacheKey);if(Cache::has($cacheKey)){$info=Cache::get($cacheKey);}else{$info=self::with('user,comment')->where('id','=',$id)->all();Cache::set($cacheKey,$info,3600);}return$info;}publicstaticfunctiondelUserById($id){$cacheKey=self::CACHE_KEY_PREFIX.$id;if(self::where('id',$id)->delete()){Cache::rm($cacheKey);returntrue;}else{returnfalse;}}}Comment:<?phpnamespaceapp\wx\model;usethink\Model;classCommentextendsModel{//自动写入时间戳字段protected$autoWriteTimestamp='timestamp';//true开启;false关闭//创建时间字段自定义protected$createTime='created_at';//默认create_time//更新时间字段自定义protected$updateTime='updated_at';//默认update_time//设置当前模型对应的完整数据表名称protected$table='comment';publicfunctiontheme(){return$this->belongsTo('Theme');}}4.控制器Users:<?phpnamespaceapp\wx\controller;useapp\wx\model\User;usethink\Controller;usethink\Request;classUsersextendsController{publicfunctionlogin(){returnview('user/login');}publicfunctiongetInfo(Request$request){$data=$request->param();$result=$this->validate($data,'\app\wx\validate\Wxs',[],false);if(true!==$result){dump($result);exit();}if($request->isPost()){$user=newUser();$data=input('post.');$num=$user->login($data);if($num==3){$this->success('信息正确,正在为您跳转','Wx/Themes/themeList');}else{$this->error('用户名或密码有误');}}return$this->fetch('login');}publicfunctionlogout(){User::logout();$this->success('退出成功,正在为您跳转','Wx/Users/login');}}Themes:<?phpnamespaceapp\wx\controller;useapp\wx\model\Comment;useapp\wx\model\User;useapp\wx\model\Theme;usethink\Controller;classThemesextendsController{//protected$users;//protected$comment;////publicfunction__construct(User$user,Comment$comment)//{//$this->users=$user;//$this->comment=$comment;//}//列表publicfunctionthemeList(){//查询状态为1的用户数据并且每页显示10条数据$list=Theme::paginate(5);//获取总记录数$total=$list->total();//获取分页显示$page=$list->render();//模板变量赋值$this->assign('total',$total);$this->assign('list',$list);$this->assign('page',$page);//渲染模板输出return$this->fetch('theme/list');}//详情publicfunctiondetail($id){$lists=Theme::getUserById($id);//$a=$lists['content'];//渲染模板输出$this->assign('lists',$lists);return$this->fetch('theme/detail');}publicfunctionlists(){$member=newTheme();$list=$member->with('user,comment')->find()->toArray();//查询一条ID为15的用户数据;toArray()是将结果转为数组。$a=[];foreach($listas$k=>$v){}dump($list['comment']);exit();}/***删除指定资源**@paramint$id*@return\think\Response*/publicfunctiondelete(Theme$theme,$id){if($theme->delUserById($id)){$msg='删除成功';}else{$msg='删除失败';}return$msg;}}Comments:<?phpnamespaceapp\wx\controller;usethink\Controller;classCommentsextendsController{}/***显示资源列表**@return\think\Response*/publicfunctionindex($kw=''){if($kw!==''){$list=\app\demo\model\Login::where('name','like',"%$kw%")->paginate(1,false,['query'=>request()->param()]);}else{$list=\app\demo\model\Login::where('id','>',1)->paginate(3,false);}//获取分页显示$page=$list->render();//获取总记录数$total=$list->total();//模板变量赋值$this->assign('kw',$kw);$this->assign('list',$list);$this->assign('total',$total);$this->assign('page',$page);//渲染模板输出return$this->fetch('list/list');}publicfunctionadd(){return$this->fetch('login/add');}/***显示创建资源表单页.**@return\think\Response*/publicfunctionaddImage(Request$request){$a=new\app\demo\model\Login();$data['name']=$request->param('name');$data['pwd']=$request->param('pwd');//获取表单上传文件例如上传了001.jpg$file=$request->file('image');//移动到框架应用根目录/uploads/目录下$info=$file->move(Config::get('upload.upload_path'));if($info){//成功上传后获取上传信息//输出jpgecho"文件类型:".$info->getExtension();echo"<br><br>";//输出20160820/42a79759f284b767dfcb2a0197904287.jpgecho"上传文件路径:".$info->getSaveName();echo"<br><br>";//输出42a79759f284b767dfcb2a0197904287.jpgecho"文件名:".$info->getFilename();echo"<br><br>";echo$info->getPathname();}else{//上传失败获取错误信息echo$file->getError();}$data['image']=$info->getSaveName();$b=$a->save($data);if($b){$this->success('添加成功,跳转到','demo\Login\index');}else{$this->error('添加失败');}}
等于:$map['id'] =array('eq',100);不等于:$map['id'] =array('neq',100);大于:$map['id']=array('gt',100);大于等于:$map['id']=array('egt',100);小于:$map['id']=array('lt',100);小于等于:$map['id']=array('elt',100);模糊查询:$map['name']=array('like','thinkphp%');between: $map['id']=array('between','1,8'); $map['id']=array('between',array(‘1’,‘8’));in: $map['id']=array('id','1,2,,3'); $map['id']=array('notin','1,2,3');$data=db('user')->where($map)->select();更多参考:http://www.thinkphp.cn/document/314.html多条件查询:视图:控制器:
//查询条件$where["a.article_status"]=["<>",0];$where["c.status"]="normal";$where["u.status"]="normal";//查询$article=Db::name('article')->alias('a');$article=$article->where($where);//判断查询条件是否存在if(!empty($q)){//自定义查询条件|分割,and连接$article=$article->where('a.title|u.nickname|c.nickname',["like","%$q%"],'and');}//自定义字段$article=$article->field('a.id,a.title,a.createtime,c.nicknameascnickname,c.type,u.nickname');//关联分类定义表为c$article=$article->join('categoryc','a.category_id=c.id');//关联用户表定义表为u$article=$article->join('useru','a.user_id=u.id');//排序$article=$article->order('a.createtimedesc');//...也可拼接执行其他操作//数据查询$article=$article->select();
控制器调用/***视频上传-站三界导航*/publicfunctionvideo_add(){if(request()->isPost()){$video=$_FILES['video'];$res=upload_file($video);return$res;}}公共方法/***视频上传-站三界导航*@param$files*@paramstring$path*@paramarray$imagesExt*@returnstring*/functionupload_file($files,$path="./upload/video",$imagesExt=['mp4']){//判断错误号if($files['error']==00){$ext=strtolower(pathinfo($files['name'],PATHINFO_EXTENSION));//判断文件类型if(!in_array($ext,$imagesExt)){return1000;//非法文件类型}//判断是否存在上传到的目录if(!is_dir($path)){mkdir($path,0777,true);}//生成唯一的文件名$fileName=md5(uniqid(microtime(true),true)).'.'.$ext;//将文件名拼接到指定的目录下$destName=$path."/".$fileName;//进行文件移动if(!move_uploaded_file($files['tmp_name'],$destName)){return1001;//文件上传失败}return$destName;//上传成功,返回上传路径}else{//根据错误号返回提示信息switch($files['error']){case1:echo2000;//上传的文件超过了php.ini中upload_max_filesize选项限制的值break;case2:echo2001;//上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值break;case3:echo2002;//文件只有部分被上传break;case4:echo2003;//没有文件被上传break;case6:echo2004;//找不到临时文件夹break;case7:echo2005;//文件写入错误break;}}}
前提:文章有分类,权重,时间排序等流程:因为这个功能不算难,本来想着是否能伸手主义一次,直接去网上拷贝一下直接用,奈何百度一下发现很多都是直接用的id为参照,比当前id小的即为上一篇,反之则为下一篇,这样的话弊端就相当明显,如果在列表中加上分类,权重排序,时间排序等等,显而易见简单的根据id取值就有些误差,故重新整理一份,不仅tp5适用,其他程序也可以用,此处仅以tp5做说明上代码:$art_id=Request::instance()->param('art_id');$detail_info=Db::name("article")->where("id",$art_id)->find();//更新文章阅读次数$update_read_num=['read_num'=>$detail_info['read_num']+1,];Db::name("article")->where("id",$art_id)->update($update_read_num);//查找上一篇下一篇/*查找出全部id,组合一个数组,根据索引去判断上一个或下一个是否存在*/$where['lm']=$detail_info['lm'];//查询条件之所属栏目$where['pass']='yes';//查询条件之是否显示$all_id=Db::name("article")->field('id')->where($where)->order('pxdesc,create_time')->select();$id_array=array();foreach($all_idas$key=>$value){if($value['id']==$art_id){//定位当前//获取下一篇if(isset($all_id[$key+1])){$next_id=$all_id[$key+1]['id'];}else{$next_id='';}//获取上一篇if(isset($all_id[$key-1])){$pre_id=$all_id[$key-1]['id'];}else{$pre_id='';}}}if($next_id!=''){$next_info=Db::name("article")->field('id,article_name')->where("id",$next_id)->find();}else{$next_info='';}if($pre_id!=''){$pre_info=Db::name("article")->field('id,article_name')->where("id",$pre_id)->find();}else{$pre_info='';}$this->assign("next_info",$next_info);$this->assign("pre_info",$pre_info);前台输出:<divclass="share"><divclass="share-bg"><divclass="share-hrefpull-lefttext-left">{ifcondition="$pre_info!=''"}<ahref="{:url('home/index/news_show',['art_id'=>$pre_info.id])}">上一篇:{$pre_info.article_name}</a>{else/}<ahref="#">上一篇:没有了</a>{/if}{ifcondition="$next_info!=''"}<ahref="{:url('home/index/news_show',['art_id'=>$next_info.id])}">上一篇:{$next_info.article_name}</a>{else/}<ahref="#">下一篇:没有了</a>{/if}</div><divclass="text-rightshare-rpull-right"><ahref="{:url('home/index/news',['art_type'=>$art_type_name.id])}">返回</a></div></div></div>
常用多久之前functiondateline($date){//当前时间的时间戳$nowtimes=time();//之前时间参数的时间戳$posttimes=$date;//相差时间戳$counttime=$nowtimes-$posttimes;//进行时间转换if($counttime<=10){return'刚刚';}elseif($counttime>10&&$counttime<=30){return'刚才';}elseif($counttime>30&&$counttime<=60){return'刚一会';}elseif($counttime>60&&$counttime<=120){return'1分钟前';}elseif($counttime>120&&$counttime<=180){return'2分钟前';}elseif($counttime>180&&$counttime<3600){returnintval(($counttime/60)).'分钟前';}elseif($counttime>=3600&&$counttime<3600*24){returnintval(($counttime/3600)).'小时前';}elseif($counttime>=3600*24&&$counttime<3600*24*2){return'昨天';}elseif($counttime>=3600*24*2&&$counttime<3600*24*3){return'前天';}elseif($counttime>=3600*24*3&&$counttime<=3600*24*30){returnintval(($counttime/(3600*24))).'天前';}else{returndate("Y年m月d日",$posttimes);}}数字没样式的代码:/*文章发布多少时间前*/functionTimeRule($time){$startdate=date('Y-m-dH:i:s',$time);//时间戳转日期(要是日期的话可以不用转)$enddate=date('Y-m-dH:i:s');//当前日期$date=floor((strtotime($enddate)-strtotime($startdate))/86400);$hour=floor((strtotime($enddate)-strtotime($startdate))%86400/3600);$minute=floor((strtotime($enddate)-strtotime($startdate))%86400%3600/60);$second=floor((strtotime($enddate)-strtotime($startdate))%86400%60);if($date>90){return'很久前';}elseif($date>=30&&$date<=90){returnfloor($date/30).'个月前';}elseif($date>0&&$date<30){return$date.'天前';}elseif($hour<24&&$hour>0){return$hour.'小时前';}elseif($minute<60&&$minute>0){return$minute.'分钟前';}elseif($second<60&&$second>0){return$second.'秒前';}}数字有样式代码:/*文章发布多少时间前*/functionTimeRule($time){$startdate=date('Y-m-dH:i:s',$time);//时间戳转日期(要是日期的话可以不用转)$enddate=date('Y-m-dH:i:s');//当前日期$date=floor((strtotime($enddate)-strtotime($startdate))/86400);$hour=floor((strtotime($enddate)-strtotime($startdate))%86400/3600);$minute=floor((strtotime($enddate)-strtotime($startdate))%86400%3600/60);$second=floor((strtotime($enddate)-strtotime($startdate))%86400%60);if($date>90){return"<spanstyle='color:red;'>很久之前</span>";}elseif($date>=30&&$date<=90){return"<p><spanstyle='color:red;'>".floor($date/30)."</span>个月前</p>";}elseif($date>0&&$date<30){return"<p><spanstyle='color:red;'>".$date."</span>天前</p>";}elseif($hour<24&&$hour>0){return"<p><spanstyle='color:red;'>".$hour."</span>小时前</p>";}elseif($minute<60&&$minute>0){return"<p><spanstyle='color:red;'>".$minute."</span>分钟前</p>";}elseif($second<60&&$second>0){return"<p><spanstyle='color:red;'>".$second."</span>秒前</p>";}}在控制器中调用公共函数:publicfunctiontimeShow(){$startdate="2017-6-307:40:00";$t=TimeRule($startdate);echo$t;}在前台中调用公共函数://tp5.0<td>{$v.add_time|TimeRule}</td>传参|方法//tp5.1raw(tp5.1手册使用函数中有解释)<td>{$v.add_time|TimeRule|raw}</td>传参|方法|raw不使用(默认)转义
order方法属于模型的连贯操作方法之一,用于对操作的结果排序。->order('sortdesc,iddesc')用法如下:Db::table('think_user')->where('status=1')->order('iddesc')->limit(5)->select();注意:连贯操作方法没有顺序,可以在select方法调用之前随便改变调用顺序。支持对多个字段的排序,例如:Db::table('think_user')->where('status=1')->order('iddesc,status')->limit(5)->select();如果没有指定desc或者asc排序规则的话,默认为asc。如果你的字段和mysql关键字有冲突,那么建议采用数组方式调用,例如:Db::table('think_user')->where('status=1')->order(['order','id'=>'desc'])->limit(5)->select();