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,更新副表,主表不变

posted @ 2024-06-10 01:39  79524795  阅读(7)  评论(0编辑  收藏  举报