ThinPHP 8最新版框架学习--持续更新中
官方手册 https://doc.thinkphp.cn/v8_0/setup.html
1.下载安装TP8
必须用composer安装,
composer create-project topthink/think tp
要注意的是你的PHP版本必须>=8,才能正常安装,否则,你会下载成TP6的!
2.开启多应用
官网教程https://doc.thinkphp.cn/v8_0/multi_app_model.html
但是我安装的时候有报错 报错内容如下:
PHP Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112
Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112
解决方案
第一步更新composer composer self-update
很不幸我更新composer时候又报错
[root@VM-16-6-centos newtp.79524795.vip]# composer self-update
PHP Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112
Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112
[root@VM-16-6-centos config]# composer self-update
PHP Fatal error: Uncaught Error: Call to undefined function Composer\XdebugHandler\putenv() in phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Process.php:98
Stack trace:
#0 phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Status.php(59): Composer\XdebugHandler\Process::setEnv()
#1 phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/XdebugHandler.php(101): Composer\XdebugHandler\Status->__construct()
#2 phar:///usr/bin/composer/bin/composer(28): Composer\XdebugHandler\XdebugHandler->__construct()
#3 /usr/bin/composer(29): require('...')
#4 {main}
thrown in phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Process.php on line 98
Fatal error: Uncaught Error: Call to undefined function Composer\XdebugHandler\putenv() in phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Process.php:98
Stack trace:
#0 phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Status.php(59): Composer\XdebugHandler\Process::setEnv()
#1 phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/XdebugHandler.php(101): Composer\XdebugHandler\Status->__construct()
#2 phar:///usr/bin/composer/bin/composer(28): Composer\XdebugHandler\XdebugHandler->__construct()
#3 /usr/bin/composer(29): require('...')
#4 {main}
thrown in phar:///usr/bin/composer/vendor/composer/xdebug-handler/src/Process.php on line 98
[root@VM-16-6-centos config]#
然后我去宝塔里面对PHP进行重载配置
,重启
,并且删除了禁用函数putenv
proc_open
,然后安装了fileinfo
扩展
再次运行更新composer composer self-update
再次运行开启多应用 composer require topthink/think-multi-app
此时没有报错了。
3.快速安装应用
直接终端运行php think build admin
当你看到 Successed 时候,表示你已经成功创建应用
4.查询
获取最后一条查询语句的SQL
$sql = Db::getLastSql();
批处理,下面代码标识每隔三个 就运行一下foreach(处理大量数据)
Db::name('user')->chunk(3,function($users){
foreach($users as $user){
var_dump($user);
}
echo 1;
});
游标查询,为了解决内存开销,每次读取一行,并返回到下一行再读取;(处理大量数据)
$user = Db::name('user')->cursor();
5.新增数据
新增数据后返回新增的数据ID
Db::name('user')->insertGetId($data);
在日常使用insert新增表数据时候,如果有一个字段名字不对 ,那么就会报错,但是有一种方法可以忽略错误,依旧添加,不裹那个字段就没有值
Db::name('user')->strick(false)->insert($data);
如果我们的数据库是Mysql,可以支持我们replace写入
insert和replacr insert的区别,就是前者标识:表中存在相同主键id则报错。
后者则会对这个id的数据进行修改
Db::name('user')->insert($data);
Db::name('user')->replace->insert($data);
批量新增数据
$data = [
[
'name'=>'马邦德',
'age'=>'38',
'datails'=>'我是马邦德',
],[
'name'=>'张麻子',
'age'=>'38',
'datails'=>'我是张麻子',
],
... ... ...
];
全部新增
Db::name('user')->insertAll(data);
批量新增
Db::name('user')->limit(100)->insertAll(data);
6.查询表达式(快捷方式查询)性能更好,优先使用
whereLike/whereNotLike 模糊查询
Db::name('user')->where('name', 'like', 'thinkphp%')->select();
Db::name('user')->where('name', 'like', ['%think','php%'],'OR')->select();
Db::name('user')->whereLike('name','thinkphp%')->select();
Db::name('user')->whereNotLike('name','thinkphp%')->select();
whereBetween/whereNotBetween 区间查询
Db::name('user')->where('id','between','1,8')->select();
Db::name('user')->whereBetween('id','1,8')->select();
Db::name('user')->whereNotBetween('id','1,8')->select();
whereIn/whereNotIn 在/不在查询
Db::name('user')->where('id','in','1,5,8')->select();
Db::name('user')->where('id','in',[1,5,8])->select();
Db::name('user')->whereIn('id','1,5,8')->select();
Db::name('user')->whereNotIn('id','1,5,8')->select();
NULL/ NOT NULL 查询字段是否(不)是Null,例如
Db::name('user')->where('name', null)->where('email','null')->where('name','not null')->select();
Db::name('user')->where('title','=', 'null')->where('name','=', 'not null')->select();
Db::name('user')->whereNull('name')->whereNull('email')->whereNotNull('name')->select();
EXP:表达式.EXP标识多写一段自定义SQL语句,如第三行代码更清晰
Db::name('user')->where('id','in','1,3,8')->select();
Db::name('user')->where('id','exp',' IN (1,3,8) ')->select();
Db::name('user')->where('id','exp',' > 4 and id < 8')->select();
Db::name('user')->whereExp('id', 'IN (1,3,8) ')->select();
Db::name('user')->whereExp('id', '<8 and id >4')->select();
7,索引查询
二纬索引数组查询
Db::name('user')->where([
["id","<","11"],
["age",">","20"],
])->select();
一纬索引数组查询
Db::name('user')->where([
"id" =>"11",
"age" =>"20",
])->select();
很多查询条件时候 可以赋值给一个变量,进行查询
$where = [];
$where[] =["id","<","11"];
$where[] =["age",">","20"];
Db::name('user')->where($where)->select();
8.拼装高级查询
|竖线表示 查询name like王 or title like王
Db::name('user')->where('name|title','like','%王%')->select();
& 表示 查询name like王 and title like王
Db::name('user')->where('name&title','like','%王%')->select();
9.第七第八结合一起
$where1 = [
["name","like","%王%"],
["title","=",null]
];
$where1 = [
["sex","=","女"],
["title","esp",Db::raw("IS NOT NULL")]
];
Db::name('user')->where([$where1,$where2])->select(); 查不出来的
Db::name('user')->whereOr([$where1,$where2])->select();能查出来
10.模型
创建模型文件 User.php,注意文件名字和类名一致,和数据库名称也一致
数据库名字 user,则模型为User
数据库名字 user_acc,则模型为UserAcc
<?php
namespace app\model;
use think\Model;
class User extends Model{
}
重新设置表名字设置主键
<?php
namespace app\model;
use think\Model;
class User extends Model{
protected $name = 'adminuser'; //设置新表名字
protected $pk = 'uid'; //设置主键
}
初始化 第一运行
<?php
namespace app\model;
use think\Model;
class User extends Model{
public static function init(){
echo '初始化';
}
}
新增数据 静态方法
<?php
$user = User::create([
"name"=>"逍遥",
"age"=>"19",
"sex"=>"男",
"datails"=>"我是你爸爸",
]);
删除数据
$user = User::find(21); 找到并删除
$user->delete();
User::destroy(21); 直接删除
User::destroy([1,2,3,4,5]);
User::where('id','<',12)->delete();
User:destroy(function($query){ 闭包模式删除
$query->where('id','>',15)
})
修改数据
当修改的数据和数据库字段的数据不一样时候,直接会更新,如果不一样时候 不会更新
$user = User::find(12);
$user->details = "我不是你爸爸";
$user->save();
echo $user;
当修改的数据和数据库字段的数据一样时候,加了force也会直接更新,更新时间会更新
$user = User::find(12);
$user->details = "我不是你爸爸";
$user->force->save();
echo $user;
$user->age = Db::raw("age + 2") 年龄新增2
返回的是修改内容
return User::update(["id"=>12,"name"=>"虎爷"]);
返回的是修改内容但是不返回id
return User::update(["name"=>"虎爷"],["id"=>12]);
返回的是修改内容,第三个参数表是限制你修改的内容,允许修改什么字段 就写什么字段。
return User::update(["name"=>"虎爷","title"=>"我是河南的"],["id"=>12],["name"]);
查询
查询一条
User::find(21);
查询所有
User::select();
也就相当于wherein查询
User::select([1,2,5]);
查询id小于5的
User::where('id','<',5)->select();
查5条以id从大到小
User::limit(5)->order("id","desc")->select();
找到所有的数据数量
User::count();
支持大量的快捷方式
User::whereLike("name","%王%")->select();
做废弃字段
废弃完了之后用模型的增删改查操作就不会再用这个废弃字段
protected $disuse = ["age","detailes"];
只读字段
用来保护某些特殊字段不被修改,一旦写入 不可修改
protected $readonly = ["age","detailes"];
获取器 ,获取器是针对查询的
当使用模型时候,可以用获取器来处理状态字段
有效方法名为 get+字段名+Attr(注意字段名第一个字母为大写)
使用模型查询时候,会自动运行这个方法,从而获取到对应的文本文字
业务代码
User::select();
模型方法
public function getStatusAttr($value,$data)
{
$status = [-1=>"删除",0=>"冻结",1=>"正常",2=>"审核"];
return $status[$value];
}
模型方法里面$data,就表示传来的值,也就是查询出来的数据,$data[字段A,字段B,字段C,,,,]
可以处理更为复杂的逻辑判断
业务代码 获取原始数据
$user = User::find(1);
echo $user->getData('status') 获取原始数据
echo $user->status; 获取器修改过后的代码
关于动态获取器,直接在业务层修改代码
$user = User::select()->whitAttr('age',function($value){
return $value +100;
})
var_dump($user);
修改器 ,修改器是针对写入修改的
业务层
User::create([
'name'=>'虎爷',
'age'=>'58',
'sex'=>'男性',
'details'=>'我是虎爷',
])
模型层
public function setAgeAttr($value){
return $value + 100;
}
搜索器
搜索器 ,模糊查名字
模型层 对应的是 Name字段
public function searchNameAttr($query,$value,$data)
{
$query->whereLike('name',"%".$value."%");
}
// 业务层 name就是模型层里面的searchNameAttr,
$user = User::withSearch(['name'],[
"name"=>"李"
])->select();
查询结果就是模糊查询name字段 李 的值
加时间查询
模型层
// 搜索器:范围时间
public function searchCreateTimeAttr($query,$value,$data)
{
//注意这个时间查询$value要传递进来数组两个值,起始时间 和结束时间
$query->whereBerweenTime("create_time",$value[0],$value[1]);
}
业务层
$user = User::withSearch(['name','caeate_time'],[
"name"=>"李",
"caeate_time"=>["2020-12-12","2023-12-12"],
])->select();
另外业务层依旧可以附加查询条件->where('sex','女')
$user = User::withSearch(['name','caeate_time'],[
"name"=>"李",
"caeate_time"=>["2020-12-12","2023-12-12"],
])->where('sex','女')->select();
软删除
首先要引入,然后设置软删除
use think\model\concern\SoftDelete;
class User extends Model
{
use SoftDelete;
}
数据库字段设定 delete_time
模型代码
User::destroy(1);//软删除
User::destroy(1,true);//真实删除
$user = User::find(1);
$user->delete();//软删除
$user->force->delete();//真实删除
开启软删除之后,搜索数据时候,会自动屏蔽这些数据
在开启软删除的前提下,使用withTrashed()方法取消屏蔽软删除的数据,也就是全部查询
User::withTrashed()->select();
如果想查询被软删除的数据,使用onlyTrashed()方法实现即可,也就是只查询软删除的数据
User::onlyTrashed()->select();
如果要真实的删除已经是软删除的数据,那么需要先将它恢复,再真实删除
restore()方法是恢复
$user = User::onlyTrashed*()->find(23);
$user->restore();
$user->force->delete();//真实删除
模型事件(模型事件是指在进行模型的查询和写入操作的时候触发的操作行为。)
查询后
protected static function onAfterRead($user){
echo '执行了事件'.$user->id;
}
新增前
protected static function onBeforeInsert($user){
echo '执行了事件'.$user->id;
}
新增后
protected static function onAfterInsert($user){
echo '执行了事件'.$user->id;
}
更新前
protected static function onBeforeUpdate($user){
echo '执行了事件'.$user->id;
}
更新后
protected static function onAfterUpdate($user){
echo '执行了事件'.$user->id;
}
写入前
protected static function onBeforeWrite($user){
echo '执行了事件'.$user->id;
}
写入前
protected static function onAfterWrite($user){
echo '执行了事件'.$user->id;
}
删除前
protected static function onBeforeDelete($user){
echo '执行了事件'.$user->id;
}
删除后
protected static function onAfterDelete($user){
echo '执行了事件'.$user->id;
}
恢复前
protected static function onBeforeRestore($user){
echo '执行了事件'.$user->id;
}
恢复后
protected static function onAfterRestore($user){
echo '执行了事件'.$user->id;
}
模型关联
1对1关联 hasOne,hasWhere模式(通过主表操作副表)
user表字段id
,name
,title
user_main表字段id
,user_id
,main
数据库设置user_main表的user_id为外键绑定到user的id
副表模型层
class Main extends Model
{
}
主表模型层
class User extends Model
{
public function abc()
{
retrn $this->hasOne(Main::class);
}
}
业务层
//------------hasOne---------
$user = User::find(21);
$user->abc; //获取副表数据
$user->abc->save(['main'=>'我要修改咯']); //修改副表数据
$user->abc()->save(['main'=>'我要新增咯']); //新增副表数据
//--------------hasWhere-----------------
在主表的模型层里面。通过副表的id查找主表的数据
$user = User::hasWhere("main",["id"=>2])->find();
闭包写法
$user = User::hasWhere("main",function($query){
$query->where('id','=',2)
})->find();
1对1关联 belongsTo模式(通过副表操作主表)
副表模型层
class Main extends Model
{
public function touser()
{
retrn $this->belongsTo(Main::class);
}
}
主表模型层
class User extends Model
{
public function abc()
{
retrn $this->hasOne(Main::class);
}
}
业务层
$user = Main::find(21);
$user->touser; 查询主表数据
$user->touser->save(['main'=>'我要修改咯']); //修改副表数据
$user->touser()->save(['main'=>'我要新增咯']); //新增副表数据
1对多关联hasMany模式
主表模型层
class User extends Model
{
public function abc()
{
retrn $this->hasMany(Main::class);
}
}
业务层
$user = User::find(48);
$user->abc->where('id','>',10); 查询副表中user_id 等于48 并且 id大于10的
$user->abc()->where('id','>',10)->select(); 查询副表中user_id 等于48 并且 id大于10的
两者的区别就是数组下标的区别,第一个不会重新排序,第二个会重新排序
查副表中 user_id相同 的 条数大于等于2的主表数据
has方法 查询关联副表的主表内容,比如大于等于2条的主表记录
也就是说 附表中的外键条数数量 大于等于2
$user = User::has('abc','>=',2)->select();
删除主表副表数据
$user = User::with('abc')->find(48); //删除主表id为48的数据
$user->together(['abc'])->delete(); //删除副表user_id为48的数据
如果代码报错了,就要仔细看下外键绑定属性了:外键绑定属性
空,RESTRICT,NO ACTION
删除:副表记录不存在时候,主表才能删除,删除副表,主表不变
更新:从表记录不存在时,主表才可以更新,更新副表,主表不变
CASCADE
删除:删除主表时自动删除副表,删除副表,主表不变
更新:更新主表时自动更新副表,更新副表,主表不变
SET NULL
删除:删除主表时自动更新副表值为NULL,删除副表,主表不变
更新:更新主表时自动更新副表值为NULL,更新副表,主表不变
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?