当前位置: 首页 > news >正文

ThinkPHP快速使用手册

目录

介绍

安装(windows环境)

安装Composer

安装ThinkPHP

目录结构

配置文件

第一个接口(Controller层)

Hello World

 自定义Controller

请求参数

获取查询参数(Get请求)

获取指定请求参数 

获取所有URL的请求参数

获取json数据(Post)

获取JSON数据中的属性

一些问题

响应参数

路由

基础路由映射

 路由写法解析

模型(Model)

模型的定义

模型使用测试

模型的设置

设置表名

 设置主键

模型字段的设置

废弃字段

访问数据库 

数据库的连接

增删改查(CURD)

新增

删除 

更新/修改

查询

查询单条

获取多条数据

模糊查询

 多条件

 排序

聚合函数的使用

分页查询

原生查询

部署

部署前准备 

部署方式一:内置服务器直接启动  

部署方式二:使用Nginx服务器

最后


介绍


 官方介绍 

ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。

ThinkPHP诞生十七年来一直秉承简洁实用的设计原则,在保持出色的性能和至简代码的同时,更注重易用性

遵循Apache2开源许可协议发布,意味着你可以免费使用ThinkPHP,甚至允许把你基于ThinkPHP开发的应用开源或商业产品发布/销售。


本文章主要是针对已有其他后端开发框架基础的人群,如SpringBoot(Java),Express(NodeJS) 等。

这样,阅读本文章你就可以快速了解ThinkPHP框架如何ORM的与数据库做交互,提供访问接口。 

 ThinkPHP为MVC架构,但本文章不说明视图层(V),使用接口测试工具apifox来测试ThinkPHP创造出的接口。 

安装(windows环境)

安装Composer

我们安装ThinkPHP之前,要先去安装Composer

为什么要安装composer?

因为ThinkPHP的下载需要通过Composer来进行

Composer是一个PHP的依赖管理工具,可以用于管理项目中的PHP库和包的依赖关系。

类似于NodeJS中的npm包管理器也类似前端脚手架构建vue项目的Vite

 安装步骤 

1. 下载Composer安装包

访问官方下载地址:Composer下载https://doc.thinkphp.cn/v8_0/setup.html

2. 执行下载的.exe安装引导程序,无脑下一步。

其中需要注意的勾选:

3. 检查安装结果:命令行输入composer。

看见输出就好了。

安装ThinkPHP

安装好了composer之后,我们就能使用composer"脚手架"来创建ThinkPHP基础项目了。 

使用脚手架去构建TP(ThinkPHP)基本项目需要下载代码、依赖包等文件,而Composer的下载服务器在国外,直接下载会很慢,因此我们可以配置一下国内的镜像源。

1. 安装前配置国内镜像:

命令:composer config -g repo.packagist composer 镜像源地址

阿里云: https://mirrors.aliyun.com/composer/ 

华为云: https://repo.huaweicloud.com/repository/php/

例如执行命令: 配置阿里国内镜像源

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

2. 切换到你PHP网站根目录(www目录)下执行安装命令

composer create-project topthink/think tp6

命令是创建一个ThinkPHP项目。(tp6为根目录名称,可自定义)

这个操作类似于前端我们使用vite脚手架构建vue项目类似 。

3. 运行测试

cd进入刚创建的tp6目录,执行运行命令:php think run

看到输出信息:项目运行在了“内置服务器”的8000端口。

通过访问URL:localhost:8000 即可访问项目首页。

 

这样我们的ThinkPHP基本项目的构造就完成了。 

上面提到了“内置服务器”,是基于 PHP 内置的 CLI 开发服务器

本地开发调试的时候我们直接使用内置服务器是可行的。

但是在部署到生产环境的时候,建议还是要部署到Apache或Nginx上。

目录结构

上面说了Composer将像是一个脚手架帮我们去构建特定结构的ThinkPHP项目。

那么接下来我们就可以看看生成的这个项目结构长啥样。

目录还是不少,下面我会说明几个较为常用的说明:

1. app目录:是应用目录,我们就在这个目录进行编码,例如接口的编写。

2. config是配置目录,里面存放着各类配置文件,如数据库的配置。

3. public是公共目录,对外访问目录,像上面我们通过访问localhost:8000显示的页面就是这个目录中的index.php文件。

4. route是定义路由的目录,就是定义我们的接口URL以什么样子暴露出去让前端进行调用。

 更详细的目录和文件说明,我们可以访问官方文档进行查看:ThinkPHP目录结构

配置文件

脚手架构建的这个基础项目中的配置文件很多,目前我们可以就关注一个

就是“database.php”,顾名思义就是数据库连接的配置。

我们展开/config目录看看其中的各种配置文件。

总之,后续我们要配置一些参数,如数据库的连接参数,我们就到/config下找就好。

第一个接口(Controller层)

接下来,我们进行正题吧。

让我们一起来写出ThinkPHP的第一个"Hello World"接口 。

Hello World

打开文件controller/Index.php

<?php
namespace app\controller;use app\BaseController;class Index extends BaseController
{// 输出hello worldpublic function hi(){return 'hello world';}}

php think run 启动项目,apifox访问接口localhost:8000/index/hi

可以看到,我们通过访问方式为:类名/方法名 

通过上面实践,我们就能知道一种接口访问的方式(后面会讲到路由访问)。

 自定义Controller

值得注意的是:如果我们要在controller目录下新建新的Controller,如UserController,需要文件名和类名保持一致。

例如,我们下面创建自定义User控制器,专门用来处理用户数据相关的请求。

BaseController 

我们通过继承BaseController (基础控制器)使得我们自定义的控制器功能得到扩展。

例如继承后我们就能通过$this去获取当前请求的一些参数。

我们可以看看BaseController中的内容:

请求参数

这里说的是如何获取前端调用接口时传入的请求参数。 

下面说明获取:查询参数对象参数,至于"路径参数"在下面的路由章节会提到。

获取查询参数(Get请求)

获取参数的方式有很多种,下面介绍两种:1.Request对象获取  2.助手函数获取

获取指定请求参数 

访问:/UserController/test1?name=tom

 接口代码:

use think\facade\Request; // 引入Requestpublic function test1(){// 方法一:使用 Request 类获取请求参数halt(Request::param("name"));// 方法二:助手函数获取halt(input("name"));
}

halt() 输出显示:

获取所有URL的请求参数

当我们同时传递多个参数的情况

访问:/UserController/test1?name=tom&age=18

接口代码:

public function test1(){// 方法一:使用 Request 类获取请求参数halt(Request::param());// 方法二:助手函数获取请求参数halt(input("param."));
}

halt()输出

获取json数据(Post)

 获取JSON数据 

我们通过apifox模拟发送一段json数据(post请求)

接口代码:

use think\facade\Request;public function index(){// 方法一:使用 Request 类获取请求参数halt(Request::param());// 方法二:助手函数获取请求参数halt(input("param."));
}

获取JSON数据中的属性

例如我们想要获取传入json对象中的name属性值,可以这样:

public function index(){// 方法一:使用 Request 类获取请求参数halt(Request::param()["name"]);// 方法二:助手函数获取请求参数halt(input("param.name"));
}

一些问题

 

在上面获取传入json数据的时候其实接口可读性是有点差的,因为我们没有将接口该传入的参数在方法上体现出来。

我想说的是:

// 显示声明name 和 age
public function index(String name, int age){// 函数体
}// 显示接收用户信息Json数据
public function addUser(User user){// 函数体
}

例如上面的index()方法其中就显示的定义调用该接口需要的参数,以及addUser()方法中需要User用户类型的一个对象参数。

我想这样的定义方式有SpringBoot使用经验的并不陌生。

这样的可读性是很好的,虽然规范性强了些。

 关于对象类型的参数说明:

在上面的addUser方法中我们定义了(User user)作为参数,表示我们想要接收一个User用户类型的对象/json数据。

但是需要知道ThinkPHP中并像SpringBoot那样会自动将json对象转为我们的PHP对象,所以,如果我们以上面的方式去定义参数,我们需要手动的先将json数据转为对象

所以就推荐直接使用请求对象Request::param() 或助手函数input("param.")去获取传入的参数好了,不必去那么严格的定义接口参数的定义。

如果就是想要定义对象参数的自动转换,可以去了解“封装中间件或者创建自定义请求处理器”,或者考虑更“大”一点的PHP框架,比如Laravel或者Symfony。

响应参数

大多数情况,我们不需要关注Response对象本身,只需要在控制器的操作方法中返回数据即可。

为了规范和清晰起见,最佳的方式是在控制器最后明确输出类型。

ThinkPHP中支持的输出类型:

例如想要返回json数据给客户端:

public function hello()
{$data = ['name' => 'thinkphp', 'status' => '1'];return json($data);
}

想要返回html格式

response($data);

 返回字符串

return 'Hello,ThinkPHP!';

 响应参数 

我们还可以设置响应的状态码和响应头等信息,可以这样写:

json($data)->code(201)->header(['Cache-control' => 'no-cache,must-revalidate'
]);

使用链式调用设置状态码和响应头。

路由

在上面的控制器或说是接口的定义中,我们并没有像SpringBoot或Express那样去显示的声明路由。

例如接口使用什么请求方式(Get还是Post),和显示的把URL和处理函数进行绑定等。

这一节就是说明这些问题。

在SpringBoot中我们通过注解来“隐式”绑定路由,而在ThinkPHP中的路由系统独立于Controller存在,需要显式配置。

基础路由映射

下面我们使用路由来映射控制器演示写法。

待路由的控制器:

<?php
namespace app\controller;
use app\BaseController;class UserController extends BaseController{public function test3(){return "我是路由访问的控制器方法";}
}

定义路由,打开/route/app.php文件

use think\facade\Route; // 引入RouteRoute::get('user/test3', 'UserController/test3');

测试路由访问:

 路由写法解析

上面的路由语法:Route::快捷方法名('路由表达式', '路由地址');


关于快捷方法名有:

 关于路由表达式:

说的就是我们自定义的请求URL的地址。

当然表达式定义上还可以说明路径参数,可以这样写:

Route::get('user/test3/:name', 'UserController/test3');

控制器代码: 

值得注意的是:在路由上定义的路径参数名要和控制器参数名相同。 

模型(Model)

 这里的模型在SpringBoot中体现为实体类

我们能使用模型来和数据库表的映射关系,也就是ORM的一个重要组成。

模型的定义

1.模型目录创建:app/model

2.创建的模型名称要和数据表名一致(大驼峰映射) 

例如创建一个User模型: 

User模型对应user数据表:

模型使用测试

测试前到配置文件config/database.php中配置好数据库连接信息。

我们通过这个数据表映射出的模型去做查询测试

use app\model\User; // 导入User类/模型// 获取用户表数据
public function getUserData(){$users = User::select(); // 直接用User模型快捷查询数据halt(json($users));
}

访问控制器: 

发现可以获取到user表的所有数据,至于User::select()的写法先不用纠结,这是使用模型查询数据的一种方式,下面会介绍到。

 

模型的设置

模型对应数据表是我们已经明确了的,在上面的模型测试访问中也是成功了的。

可以查询到数据是因为框架根据我们的类名去查询数据表名,然后获取数据。

设置表名

如果我们的类名和表明不一致,我们可以在模型中进行设置:

class ABC extends Model
{protected $table = 'user'; // 数据表名称
}

 上面代码可以看到,我们的模型名为ABC,而我们的表名为user,直接查询必然会映射失败导致数据无法查询,我们可以通过$table属性对表名进行定义

 设置主键

默认会识别主键名称为“id”,如果你的主键名称是其他需要设置$pk属性值。 

use think\Model;class User extends Model
{protected $pk = 'uid'; // 主键名称
}

模型字段的设置

这使得我们可以在模型中设置字段名,就是显示的设置类的成员属性。

为什么要显示设置字段名?

在上面的模型测试中我们没有设置模型的字段名依然可以查询出数据。

那么为什么我们还要显示的声明字段名呢?

1. 一方面是可读性,使我们看到模型就知道数据表有哪些字段

2. 提升性能,当我们默认使用模型映射查询数据时,首先框架会根据数据表名先查询出表的所有字段,再使用查询出来的字段查询数据,这必然就会导致多执行一次sql查询,所以如果我们能在模型中先定义,就可以省去一次sql查询。

使用$schema设置字段名

<?php
namespace app\model;use think\Model;class User extends Model
{// protected $table = 'user'; // 数据表名称// 设置表字段protected $schema = ['id'          => 'int','name'        => 'string','status'      => 'int','score'       => 'float','create_time' => 'datetime','update_time' => 'datetime',];
}

通过$schema去定义字段我们还能显示看到字段的类型

当然,模型中的字段要和数据表的字段名对上的

废弃字段

当我们在操作数据表想要忽略某个/些字段时,我们可以将字段进行设置:

class User extends Model
{// 设置废弃字段protected $disuse = [ 'status', 'type' ];
}

这样设置之后,在查询和写入的时候会忽略定义的statustype废弃字段。

访问数据库 

下面只会说明使用模型直接ORM访问数据表,而不会说明Db:table()的原始方式去查询数据。

如果对Db::table()的方式感兴趣,可以访问官方手册

数据库的连接

访问config/database.php文件:

可以看到在数据库的连接信息中,是优先使用环境变量中的连接信息的,如果环境变量中没有连接信息的参数,才会使用第二个参数。

所以,我们在本地测试中优先到.env文件中进行连接信息的配置。

这个文件名原先为.example.env ,可以改为.env。

然后进行.env配置文件配置连接信息:

关于.env文件,一般用于本地环境测试,如果后续要部署到服务器需要将.env内容注释,使用database.php文件进行配置。

增删改查(CURD)

新增

定义路由

<?phpuse think\facade\Route;Route::post("user/add", "UserController/addUser"); // 新增用户

控制器代码:

// 新增用户
public function addUser(){// 获取请求参数$data = Request::param();// 创建用户模型实例$user = new User();// 设置用户数据$user->data($data);// 保存用户数据到数据库if($user->save()){return "新增成功";}else{return "新增失败";}
}

测试访问 

save方法支持传入模型实例或实体对象实例。 

使用::create方法

public function addUser(){// 获取请求参数$data = Request::param();// 执行添加,失败会返回null,成功返回模型对象$user = User::create($data);if($user){// 成功逻辑}else{// 失败逻辑}
}

 新增多条

使用saveAll()方法。 

$user = new User;
$list = [['name'=>'thinkphp','email'=>'thinkphp@qq.com'],['name'=>'onethink','email'=>'onethink@qq.com']
];
$user->saveAll($list);

删除 

定义路由:

Route::delete('user/del/:id', 'UserController/deleteUser'); // 删除用户

控制器代码:

// 删除用户
public function deleteUser($id){// 方法一、$user = User::find($id);$user->delete();// 方法二、$res = User::destroy($id);
}

 删除多条:

// 方法1:
User::destroy([1,2,3]);
// 方法2:
User::where('id','>',10)->delete();

更新/修改

在取出数据后,更改字段内容后使用save方法更新数据。这种方式是最佳的更新方式。 

// 方法1
$user = User::find(1);
$user->name  = 'thinkphp';
$user->email  = 'thinkphp@qq.com';
$user->save();// 方法2:
User::update(['name' => 'thinkphp'], ['id' => 1]);
// 如果你的第一个参数中包含主键数据,可以无需传入第二个参数(更新条件)
User::update(['name' => 'thinkphp', 'id' => 1]);

查询

下面的内容并不完整,仅演示常用的一些查询。

可以往下过一遍看看语法,其他的方法用法都大差不差。

完整的查询方法可以到官方手册,或用的时候直接问题AI就行。 

查询单条
// 根据主键查询单条数据
$user = User::find(1);// 使用查询构造器查询满足条件的数据
$user = User::where('name', 'thinkphp')->find();

 执行find()方法后,如果没有找到数据返回null,否则返回当前模型的对象实例。

获取多条数据
// 根据主键获取多个数据
$list = User::select([1,2,3]);
// 对数据集进行遍历操作
foreach($list as $key=>$user){echo $user->name;
}

带有条件的查询多条 

$users = User::where('id', '>',10)->select();
模糊查询
 $user = User::whereLike("name", "%mao%")->select();
 多条件

如果有多条件,我们可以多次调用where()进行拼接。

$users = User::where('id', '>',10)->where("name", "like", "mao")->select();

多个where之间的连接为AND。

如果想要where之间的关系为OR,我们可以把where换成whereOr

$users = User::where('id', '>',10)->whereOr("name", "like", ""mao)->select();

 排序

在调用链上添加上order("排序字段", "排序规则(asc , desc)")

users = User::where("id" , ">", 1)->order("age", "desc")->select();
聚合函数的使用
// 获取用户表年龄最大值
$user = User::max("age");

其他的如min(), avg(), sum()是一样的用法。

分页查询
// 获取分页参数,默认每页 10 条,第 1 页
$page = Request::param('page', 1);
$limit = Request::param('limit', 10);// 查询用户数据并分页
$users = User::paginate(['list_rows' => $limit,'page' => $page
]);

原生查询

原生查询说的是我们可以手写sql语句去执行查询

public function getUsers(){$user = Db::query("select * from user");halt($user);
}

 测试访问  

部署

在我们本地开发完ThinkPHP项目后,如果想要让项目能线上访问,我们需要将项目部署到线上服务器上。这是我们要说明的问题。

我们将项目部署到服务器上,然后使用浏览器或apifox访问服务器的接口进行测试。

 

部署前准备 

 1.关闭调试模式 

将APP_DEBUG设置为false

2.数据库的配置

 把数据库的连接配置信息填好(线上可访问)。

 3.服务器环境 

部署的服务器需要安装:

  • PHP环境
  • Composer
  • Nginx

上面三个服务器的环境安装配置过程就不演示了。

 

部署方式一:内置服务器直接启动  

最直接的部署方式是直接将thinkphp项目上传到服务器,然后通过composer安装依赖后直接使用php think run将项目启动。

这种方式 仅适合本地开发调试不推荐在生产环境中使用

但是如果你的项目仅用来上线演示,不供大众使用,直接使用这种方式也无妨。

 部署步骤  

1. 上传开发好的ThinkPHP项目到服务器

2. 到项目根目录下安装依赖,命令:composer install --no-dev -o 

3. 使用命令启动项目: php think run --host=0.0.0.0 --port=9878 

  • 通过--port参数临时指定启动的端口(自定义)
  • 如果部署在云服务器上,记得将服务器防火墙云服务器的安全组端口打开

4. 访问测试就行:服务器域名或IP:自定义端口/接口路径

这种方式为什么不推荐生产环境使用?

  • 性能较差
    php think run 使用的是 PHP 自带的开发服务器,单线程、无并发处理能力,无法承受多用户访问,容易崩溃。

  • 稳定性不足
    它不是为长时间运行设计的,容易在高负载或错误情况下宕掉,不具备错误自动恢复机制。

  • 安全性较低
    内建服务器没做太多安全隔离,比如目录穿越、恶意请求防护等都非常薄弱。

  • 日志、连接管理能力差
    没有日志轮转、访问日志、慢日志、连接池等功能,排查问题不方便。

部署方式二:使用Nginx服务器

1. 上传开发好的ThinkPHP项目到服务器

2. 到上传好的项目根目录下安装依赖执行安装命令composer install --no-dev -o

3.  配置nginx,打开你自己的nginx目录下的配置文件nginx.conf

# 配置示例,请根据自己的服务器参数进行填写
server {listen 8000; # 端口,自定义server_name 你域名或服务器IP;root 你的项目路径/public;index index.php index.html;location / {if (!-e $request_filename) {rewrite ^(.*)$ /index.php?s=$1 last;break;}}location ~ \.php$ {# 这里的配置需要按照实际情况填写,看下面说明fastcgi_pass unix:/run/php-fpm/www.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}
}

配置完nginx之后,记得执行命令nginx -s reload 命令重新加载一下配置文件。  

需要注意!!

 

上面配置中的:fastcgi_pass unix:/run/php-fpm/www.sock; 一行中,需要正确配置php-fpm服务目录名称。

怎么找到该填的值呢?

我们可以通过命令 “grep "listen =" /etc/php-fpm.d/*.conf” 进行查询。

然后将查询结果填到上面的nginx配置中

例如图片输出:/run/php-fpm/www.sock

 php-fpm是什么? 

  • PHP在Web服务器(如 Nginx)中运行的核心组件
  • 例如当我们用Nginx访问一个.php 页面时,Nginx本身不会执行PHP,它会把请求转交给php-fpm去处理,处理完再把结果返回给用户。
  • 简单来说就是PHP的解释器。

 所以,我们在nginx配置中需要正确配置fpm的路径,以便使nginx能找到fpm。

4. 开启php-fpm服务

// 查看php-fpm服务状态
systemctl status php-fpm// 如果是关闭状态就启动他
systemctl start php-fpm

5. 开放文件权限

 给上传的ThinkPHP项目根目录下的public 和 runtime目录开放权限

chmod -R 775 runtime
chmod -R 775 public

以及,需要给上面执行命令grep "listen =" /etc/php-fpm.d/*.conf后输出(php-fpm)的目录开放权限。

这就是刚才在nginx中配置的php解释器,给www.sock开放权限。

这是必要的,否则会出现502报错攻击!! 

6. 测试访问

测试前记得把你在nginx配置的端口服务器防火墙云服务器安全组打开。 

最后

完整教程请访问官方手册:序言 - ThinkPHP官方手册

 

相关文章:

ThinkPHP快速使用手册

目录 介绍 安装&#xff08;windows环境&#xff09; 安装Composer 安装ThinkPHP 目录结构 配置文件 第一个接口&#xff08;Controller层&#xff09; Hello World 自定义Controller 请求参数 获取查询参数&#xff08;Get请求&#xff09; 获取指定请求参数 获取…...

文档构建:Sphinx全面使用指南 — 强化篇

文档构建&#xff1a;Sphinx全面使用指南 — 强化篇 Sphinx 是一款强大的文档生成工具&#xff0c;使用 reStructuredText 作为标记语言&#xff0c;通过扩展兼容 Markdown&#xff0c;支持 HTML、PDF、EPUB 等多种输出格式。它具备自动索引、代码高亮、跨语言支持等功能&#…...

Laravel 自定义 Artisan 命令行

1.什么是Artisan 命令行 Artisan 是 Laravel 中自带的命令行接口。Artisan 以 artisan 脚本的方式存在于应用的根目录中&#xff0c;提供了许多有用的命令。 查看所有命令行 php artisan list系统自带我很多的命令&#xff0c;大家可以自己去试一下&#xff0c;例如&#xf…...

node.js 实战——(fs模块 知识点学习)

fs 模块 也可以称之为文件系统模块&#xff0c;是node中的内置模块&#xff0c;可以实现与硬盘的交互。比如文件的创建、删除、重命名、移动&#xff0c;还有文件内容的写入、读取&#xff0c;以及文件夹的相关操作 #mermaid-svg-NAByzqTngZUOyQcY {font-family:"trebuch…...

openharmony5.0.0中C++公共基础类测试-线程相关(一)

C公共基础类测试及源码剖析 延续传统&#xff0c;show me the code&#xff0c;除了给出应用示例还重点分析了下openharmony中的实现。 简介 openharmony中提供了C公共基础类库&#xff0c;为标准系统提供了一些常用的C开发工具类&#xff0c;本文分析其实现&#xff0c;并给…...

前缀和相似题共赏

P3131 [USACO16JAN] Subsequences Summing to Sevens S P3131 [USACO16JAN] Subsequences Summing to Sevens S 思路: 一看到区间和我们应该就能马上想到把这个区间拆分成两个前缀相减的形式 式子为:(Pre[r] - Pre[l-1]) % 7 0 Pre[r] % 7 Pre[l-1] % 7 Pre[r] Pre[l-1] 所…...

一文读懂https

http和https的关系 http&#xff0c;应用层协议&#xff0c;由于采用明文传输&#xff0c;不安全&#xff0c;还有很多其他安全问题&#xff0c;为此就衍生出了同为应用层协议的https。https在http的基础上引入了SSL&#xff08;Secure Socket Layer 安全套接层&#xff09;和…...

为什么 requests 不是 python 标准库?

为什么 requests 不是 python 标准库&#xff1f; requests开发者Kenneth之前还严肃地征求过这个意见&#xff0c;感兴趣的可以看看 https://github.com/psf/requests/issues/2424 我大致瞅了下&#xff0c;基本都不赞成requests加入python标准库&#xff0c;主要有以下两个原…...

[STM32] 4-1 UART与串口通信

文章目录 前言4-1 UART与串口通信串口简介串口接线 数据帧串口的数据帧格式空闲位起始位数据位校验位&#xff08;位于数据位内部&#xff09;奇偶校验 停止位 异步通信和波特率同步通信异步通信波特率 流控的概念串口流控的工作原理 随堂测试问题1:说出Tx、Rx、CTS、RTS、VCC、…...

7-1 三种语言的单词转换

编写程序实现&#xff1a;首先从键盘输入若干个中文与英文单词的偶对&#xff0c;以空行作结束标记&#xff1b;再输入若干个英文与丹麦文单词的偶对&#xff0c;以空行作结束标记。然后输入一个中文单词&#xff0c;输出对应的丹麦文单词&#xff1b;若不存在该单词&#xff0…...

高防IP是什么

"高防IP"是指"高防护IP"&#xff0c;是一种防御DDoS&#xff08;分布式拒绝服务攻击&#xff09;的网络安全服务。在分布式拒绝服务攻击中&#xff0c;攻击者会利用许多不同的计算机或者其他设备&#xff0c;通过向目标发送大量的网络请求来尝试使目标服务…...

基于javaweb的SSM宠物商城设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

《TCP/IP详解 卷1:协议》之第六章:ICMP:Internet控制报文协议

目录 一、ICMP协议 二、ICMP 报文格式 三、ICMP询问报文 四、ICMP 差错报告报文 五、ICMP端口不可达差错 一、ICMP协议 ICMP&#xff08;Internet Control Message Protocol&#xff0c;互联网控制消息协议&#xff09;是网络层的一个核心协议&#xff0c;用于在IP主机、…...

SpringBoot项目,密码加密之“BCrypt加密”

前言 这种方法&#xff0c;是当前推荐的密码加密方式。&#xff08;现在不推荐使用MD5加密了&#xff09;。 如何在springboot项目中&#xff0c;使用bcrypt加密&#xff1f;请分步骤详细介绍一下 一.在Spring Boot项目中使用BCrypt加密的详细步骤 BCrypt是当前推荐用于密码存…...

外贸获客新革命:基于AI的搜索引擎排名攻防战——48小时抢占谷歌TOP3的技术逻辑与实战路径

一、传统SEO的三大死亡陷阱&#xff08;为什么你的客户正在被AI截流&#xff1f;&#xff09; 关键词荒漠化 人工筛选关键词效率不足1%&#xff0c;95%的B2B采购商使用长尾词搜索&#xff08;如"IP68 waterproof LED strip for outdoor projects"&#xff09;而非通…...

0101基础知识-区块链-web3

文章目录 1 web3学习路线2 区块链简史2.1 区块链2.2 公共账本2.3 区块链的设计哲学2.3.1 去中心化2.3.2 共识2.3.2.1 上链2.3.2.2 共识算法 3 web3面向资产的互联网3.1 安全性和去中心化的权衡 4 智能合约4.1 以太坊智能合约4.2 去中心化应用 5 小结结语 1 web3学习路线 参考下…...

SpringMVC从入门到上手-全面讲解SpringMVC的使用.

一、springmvc介绍 MVC全称Model View Controller&#xff0c;是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中&…...

解锁现代生活健康密码,开启养生新方式

在科技飞速发展的当下&#xff0c;我们享受着便捷生活&#xff0c;却也面临诸多健康隐患。想要维持良好状态&#xff0c;不妨从这些细节入手&#xff0c;解锁科学养生之道。​ 肠道是人体重要的消化器官&#xff0c;也是最大的免疫器官&#xff0c;养护肠道至关重要。日常可多…...

绿色森林人文生活纪实摄影Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色介绍 绿色森林人文生活纪实摄影 Lr 调色&#xff0c;是借助 Lightroom 软件&#xff0c;对以绿色森林为背景&#xff0c;记录人文生活场景的纪实摄影作品进行后期调色处理。通过调整画面的色彩、光影、对比度等参数&#xff0c;让画面融入绿色森林的独特氛围&#xff0c;真…...

【项目篇】仿照RabbitMQ模拟实现消息队列

大家好呀 我是浪前 项目篇&#xff1a;仿照RabbitMQ模拟实现消息队列 今天是项目的第一篇&#xff0c;我们先来创建出最核心的几个类。 仿照RabbitMQ模拟实现消息队列 创建Exchange类MessageQueue类Binding类Message类1&#xff1a;BasicProperties类2&#xff1a;正文部分3&a…...

JAVA程序获取SVN提交记录

1.获取文件提交记录 private String userName "userName "; //svn账号 private String password "password "; //svn密码 private String urlString "urlString "; //svnurl 换成自己对应的svn信息 package com.tengzhi.common.dao;import…...

从检索到生成:RAG 如何重构大模型的知识边界?

目录 一、技术演进图谱说明 二、RAG 技术概述 &#xff08;一&#xff09;核心思想说明 &#xff08;二&#xff09;RAG 发展路径与研究范式 三、Naive RAG&#xff1a;最基础的检索增强生成范式 &#xff08;一&#xff09;Naive RAG 的标准流程 1. 索引&#xff08;In…...

rabbitmq-spring-boot-start版本优化升级

文章目录 1.前言2.优化升级内容3.依赖4.使用4.1发送消息代码示例4.2消费监听代码示例4.3 brock中的消息 5.RabbmitMq的MessageConverter消息转换器5.1默认行为5.2JDK 序列化的缺点5.3使用 JSON 进行序列化 6.总结 1.前言 由于之前手写了一个好用的rabbitmq-spring-boot-start启…...

SVN仓库突然没有权限访问

如果svn仓库突然出现无法访问的情况&#xff0c;提示没有权限&#xff0c;所有账号都是如此&#xff0c;新创建的账号也不行。 并且会突然提示要输入账号密码。 出现这个情况时&#xff0c;大概率库里面的文件有http或者https的字样&#xff0c;因为单独给该文件添加权限导致…...

vue实现静默打印pdf

浏览器中想要打印文件&#xff0c;不依靠浏览器自带的打印窗口&#xff0c;想要实现静默打印&#xff08;也就是不弹出打印对话框&#xff09;&#xff0c;同时控制打印份数的功能&#xff0c;一种方式是使用vue-plugin-hiprint和本地安装客户端electron-hiprint 本来是浏览器去…...

如何开启远程桌面连接外网访问?异地远程控制内网主机

实现远程桌面连接外网访问&#xff0c;能够突破地域限制&#xff0c;随时随地访问远程计算机&#xff0c;满足远程办公、技术支持等多种需求。下面为你详细介绍开启方法。 一、联网条件 确保本地计算机和远程计算机都有稳定的网络连接&#xff0c;有联网能上网。 二、开启远程…...

数据结构与算法学习笔记(Acwing提高课)----动态规划·数字三角形

数据结构与算法学习笔记----动态规划数字三角形 author: 明月清了个风 first publish time: 2025.4.23 ps⭐️终于开始提高课的题啦&#xff0c;借的人家的号看&#xff0c;以后给y总补票叭&#xff0c;提高课的题比之前的多很多啊哈哈哈哈&#xff0c;基本上每种题型都对应了…...

RK3568平台开发系列讲解(调试篇)debugfs文件系统及常见调试节点介绍

更多内容可以加入Linux系统知识库套餐(教程+视频+答疑) 🚀返回专栏总目录 文章目录 一、什么是debugfs二、/proc/filesystems三、debugfs的挂载3.1、fstab 的文件结构3.2、手动挂载与卸载四、debugfs 常见目录有哪些4.1、/sys/kernel/debug/gpio4.2、/sys/kernel/debug/…...

数字化转型避坑指南:中钧科技如何用“四个锚点”破解转型深水区

数字化转型浪潮下&#xff0c;企业常陷入四大典型陷阱&#xff1a;跟风式投入、数据沼泽化、流程伪在线、安全裸奔化。中钧科技旗下产品以“经营帮”平台为核心&#xff0c;通过针对性方案帮助企业绕开深坑。 陷阱一&#xff1a;盲目跟风&#xff0c;为数字化而数字化 许…...

数字化转型下的批发订货系统:降本增效的关键路径

随着数字化转型的不断深入&#xff0c;越来越多的企业开始拥抱现代化的技术和工具&#xff0c;以提升业务效率、降低运营成本。批发行业&#xff0c;作为一个高度依赖库存和订单管理的行业&#xff0c;数字化转型尤为关键。传统的批发订货系统存在信息不对称、操作复杂、效率低…...

一 、环境的安装 Anaconda + Pycharm + PaddlePaddle

《从零到一实践&#xff1a;系统性学习生成式 AI(NLP)》 一 、环境的安装 Anaconda Pycharm PaddlePaddle 1. Anaconda 软件安装 Anaconda 软件安装有大量的教程&#xff0c;此处不在说明&#xff0c;安装完成之后界面如下&#xff1a; 2. 创建 Anaconda 虚拟环境 Paddl…...

Dhtmlx Gantt教程

想实现的效果 插件安装&#xff1a; npm i dhtmlx-gantt使用该插件的时候&#xff0c;直接导入包和对应的样式即可&#xff1a; import { Gantt} from "dhtmlx-gantt"; import "dhtmlx-gantt/codebase/dhtmlxgantt.css";也可以安装试用版本&#xff0c;…...

大模型框架技术全景与下一代架构演进

‌一、大模型框架概述 ‌大模型框架‌是支撑千亿级参数模型训练、推理及产业落地的技术底座&#xff0c;涵盖分布式计算、高效内存管理、多模态融合等核心模块。从GPT-3到Gemini Ultra&#xff0c;大模型框架的迭代推动AI从“作坊式实验”迈向“工业化生产”。据Gartner预测&a…...

官方不存在tomcat10-maven-plugin插件

Maven 中央仓库中没有官方的tomcat10-maven-plugin。Apache Tomcat Maven 插件项目目前仅对以下插件提供官方支持&#xff1a; tomcat6-maven-plugin tomcat7-maven-plugin tomcat8-maven-plugin tomcat9-maven-plugin 如果你想使用 cargo 命令来跑支持 Jakarta EE 的 Tomcat 1…...

vue3 el-table 右击

在 Vue 3 中使用 Element Plus 的 <el-table> 组件时&#xff0c;如果你想实现右击&#xff08;右键点击&#xff09;事件的处理&#xff0c;你可以通过监听 contextmenu 事件来实现。contextmenu 事件在用户尝试打开上下文菜单&#xff08;通常是右键点击&#xff09;时…...

第一节:核心概念高频题-Vue3响应式原理与Vue2的区别

Vue2&#xff1a;基于Object.defineProperty监听对象属性&#xff0c;需手动处理数组方法重写 Vue3&#xff1a;采用Proxy代理实现全量响应式&#xff0c;支持动态新增属性和深层嵌套对象监听 一、实现机制对比 1. Vue2&#xff1a;基于 Object.defineProperty • 原理&#…...

【锂电池剩余寿命预测】CNN卷积神经网络锂电池剩余寿命预测(Pytorch完整源码和数据)

目录 效果一览程序获取程序内容代码分享效果一览 程序获取 获取方式一:文章顶部资源处直接下载:...

web刷题笔记

2024isctf ezrce 禁用了一些关键字符&#xff0c;查询函数&#xff0c;系统执行函数&#xff0c;执行函数都有&#xff0c;空格也和斜杆也禁用了&#xff0c;但是其他一些很大一部分字符都没有禁用&#xff0c;属于关键词禁用的类型&#xff0c;正常的步骤是去查一下列表&#…...

基于FPGA 和DSP 的高性能6U VPX 采集处理板

基于FPGA 和DSP 的高性能6U VPX 采集处理板&#xff0c;是一款处理架构采用FPGADSP 的高性能的6U VPX 采集处理板。板载4 片高速ADC 共8 个采集通道&#xff0c;可支持8 路采样率最高2.6Gsps/14Bit 的模拟信号通道。 板卡FPGA 采用Xilinx 公司KU 系列的XCKU115-2FLVF1924I&…...

uniapp中使用<cover-view>标签

文章背景&#xff1a; uniapp中遇到了原生组件(canvas)优先级过高覆盖vant组件 解决办法&#xff1a; 使用<cover-view>标签 踩坑&#xff1a; 我想实现的是一个vant组件库中动作面板的效果&#xff0c;能够从底部弹出框&#xff0c;让用户进行选择&#xff0c;我直…...

【JavaScript】详讲运算符--算术运算符

1、运算符简介 运算符也叫操作符&#xff0c;通过运算符可以对一个或多个值进行运算&#xff0c;比如&#xff1a;typeof就是运算符&#xff0c;可以来获得一个值的类型&#xff0c;它会将该值的类型以字符串的形式返回,即&#xff1a;typeof 变量名的结果为字符串类型。 <…...

.NET 6 + Dapper + User-Defined Table Type

大家都知道&#xff0c;对于SQL Server IN是有限制条件的&#xff0c;如果IN里面的内容过多&#xff0c;在执行的时候会被自动截断&#xff0c;因而导致查询到的结果不是实际需要的结果。 select * from Payments where Id in (1,2,3,4,...) 为了解决上面的限制&#xff0c;可以…...

使用 Conda 创建新环境

使用 Conda 创建新环境 在使用 Conda 进行包管理和环境隔离时&#xff0c;创建新环境是一个非常常见的操作。通过创建独立的环境&#xff0c;可以避免不同项目之间的依赖冲突&#xff0c;并且能够灵活地管理各个项目的运行环境。 以下是使用 Conda 创建和管理新环境的详细步骤…...

数据为基:机器学习中数值与分类数据的处理艺术及泛化实践

数据为基&#xff1a;机器学习中数值与分类数据的处理艺术及泛化实践 摘要 在机器学习实践中&#xff0c;数据质量对模型效果的影响往往超过算法选择。本文通过详实的案例解析&#xff0c;系统阐述数值型数据与分类数据的特征工程处理方法&#xff0c;揭示数据预处理对模型泛…...

Docker镜像与容器概念解析

Docker镜像与容器概念解析 -更适合大学生宝宝体制的docker学习指南 一、Docker镜像&#xff1a;应用程序的基因库 &#xff08;1&#xff09;本质特征&#xff1a;镜像是一个只读的二进制文件包&#xff0c;相当于应用程序的”基因图谱”。就像生物体的DNA决定了生物特征&a…...

基于GMM的语音识别

语音识别是近年来发展非常迅速的一项计算机智能技术&#xff0c;广泛应用在语音控制、身份识别等多个领域。本次项目主要研究语音识别的预处理过程和特征参数的提取环节。通过对原始语音信号进行预加重和分帧、加窗&#xff0c;滤除低频干扰&#xff0c;提升对语音识别有用的部…...

K8S安全认证

一。用户认证的基本框架 在K8S集群中&#xff0c;客户端通常有两类&#xff1a; 1.User Account&#xff1a;一般独立于K8S之外的其他服务管理的用过户账号 2.Service Account&#xff1a;K8S管理的账号&#xff0c;用于为Pod中的服务进程在访问K8S提供身份标识 ApiServer是…...

咖啡机语音芯片方案-WTN6040FP-14S直接驱动4欧/3W喇叭-大功率输出

一、开发背景 随着智能家居市场的快速发展和消费者对家电产品交互体验要求的不断提高&#xff0c;语音提示功能已成为现代咖啡机产品的重要卖点之一。传统咖啡机仅依靠指示灯和简单蜂鸣器提示&#xff0c;无法满足用户对操作引导、状态反馈和个性化体验的需求。 WTN6040FP-14大…...

Vue3集成百度实时语音识别

示例 SpeechRecognitionModal.vue 组件 <template><transition name"modal-fade"><div v-if"isOpen" class"modal-overlay" click.self"handleOverlayClick"><div class"modal-container"><div…...

C# 设计原则总结

跟着视频学习的&#xff0c;记录一下最后的总结。 接口隔离&#xff1a; 单一职责&#xff1a; 里氏替换&#xff1a; 依赖倒置; 迪米特法则; 开闭原则&#xff1a;...