thinkPHP6.0实现删除和修改用户信息

  • 1.删除用户信息
  • 2.优化bootstrap资源引入方式
  • 3.浏览器的cookie与session机制
  • 4.token令牌原理
  • 5.利用token防止表单重复提交
  • 6.同步表单数据库修改
    • 参考文献:

1.删除用户信息

    删除用户信息,一般是采用Ajax发送delete请求来实现,但是这里主要是熟悉thinkPHP6.0的相关功能,因此不考虑API的封装。但是由于省去了Ajax封装,通常表单默认支持的是get请求和post请求两种方式。因此这里介绍一种新的方式,伪造delete(删除)和put(修改)请求。拿delete请求举例,其写入如下:

   <input type="hidden" name="_method"value="delete"/>

解释:其实仔细一想,原来还是很好理解的,浏览器你去要知道是哪一种请求,肯定需要知道发送的参数值。而这个参数便是method,这里是使用php能够识别的"_method"变量并传递delete值来实现的。其次,去要注意的是thinkPHP中对于数据的删除和修改资源路由都是通过url/:id实现的,传递的id便是数据在数据库中的额唯一标志id。

    回到之前的页面,重写button的删除代码如下:

 <td class="text-center"><form action="{:url('/user/'.$obj.id)}" method="post"><!--伪造请求表单--><input type="hidden" name="_method"value="delete"/><button class="btn btn-danger btn-sm btn-delete">删除</button><a class="btn btn-warning btn-sm" href="{:url('/user/'.($obj.id).'/edit')}">修改</a></form></td>

解释:这样,根据表单提交原理,当表单中没有出现type=submit的表单组件时,button会代替并具有submit功能。至于修改部分,本篇文章后半部分再来详细说明。
    当我们进行一次数据设置之后,出现如下报错提示。这应该是thinkPHP框架内部做的检测,毕竟对于数据的删除还有连接据库等相关操作:

在controller/User.php文件中写入如下方法:

 public function delete($id){return UserModel::destroy($id) ? view('../view/public/toast.html',['infos' => ['恭喜,删除成功!'],'url_text' => '去首页','url_path' => url('/user')]) : '删除失败';}

解释:重用toast提示模块,使用继承了think\model后的UserModel中的destroy方法,利用$id这个数据唯一标识实现数据的删除,这样数据删除就完成了。

2.优化bootstrap资源引入方式

    数据删除还是比较简单的,修改数据相对要复杂一点。首先描述一下模拟删除的需求:用户点击修改数据之后,会跳转到一个edit.html页面展示用户信息,并设置密码可修改,用户名和邮箱无法修改,修改信息同样要有验证。
    接下来便是具体的实现了,首先由于需要展示未修改前的用户数据。故而接上面的伪造表单做url路由重定向,跳转到用户数据展示与编辑页面edit.html.在controller/User.php中增加如下方法:

 public function edit($id){return view('edit',['obj' => UserModel::find($id)]);}

解释:edit方法用户将页面重定向到edit.html,方法中传递的$id实际上是用户数据字段唯一标识。可通过这个标识配上查询方法find找到用户具体数据,obj实际就是将用户原始数据传递到edit.html页面中。
在edit.html页面中添加如下表单,为了方便验证其实就是拿着create.html作略微修改得到的:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>新增用户页面</title><!--引入css文件--><link rel="stylesheet" href="__CSS__/bootstrap.css.map"/><link rel="stylesheet" href="__CSS__/bootstrap.css"/><link rel="stylesheet" href="__CSS__/style.css"/><!--引入js文件--><script src="__JS__/jquery-3.5.1.min.js"></script><script src="__JS__/bootstrap.js"></script><style>.create-form{margin-top: 100px;}</style>
</head>
<body>
<form class="form-horizontal create-form" role="form" action="{:url('/user/'.$obj.id)}" method="post"><div class="form-group"><label for="firstname" class="col-sm-2 control-label">用户昵称:</label><div class="col-sm-10"><input type="text" class="form-control" id="firstname" disabled name="username" placeholder="请输入用户昵称" value={$obj.username}></div></div><div class="form-group"><label for="email" class="col-sm-2 control-label" >用户邮箱:</label><div class="col-sm-10"><input type="text" class="form-control" id="email" disabled name="email" value={$obj.email} placeholder="请输入用户邮箱"></div></div><div class="form-group"><label for="newpassword" class="col-sm-2 control-label">修改密码:</label><div class="col-sm-10"><input type="password" class="form-control" id="newpassword" name="newpassword" placeholder="请输入用户密码"></div></div><div class="form-group"><label for="newpasswordnot" class="col-sm-2 control-label">重复密码:</label><div class="col-sm-10"><input type="password" class="form-control" id="newpasswordnot" name="newpasswordnot" placeholder="请输入重复密码"></div></div><div class="form-group"><label for="email" class="col-sm-2 control-label">用户状态:</label><div class="col-sm-10"><select name="status" class="form-control"><option class="disabled" value="">请选择用户状态</option><option value="0" {$obj.status =='待审核' ? 'selected' : ''} >待审核</option><option value="1" {$obj.status =='正常' ? 'selected' : ''}>正常</option></select></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><input type="hidden"  name="__token__" value="{:token()}"  /><input type="hidden" name="_method" value="put"/><button type="submit" class="btn btn-success">提交修改</button></div></div>
</form>
</body>
</html>

得到如下页面:

通过控制台查看发现是static文件中的bootstrap资源没有正确引入:
之前的资源引入为:

  'tpl_replace_string' => ['__JS__' => '../../static/js','__CSS__' => '../../static/css',]

这里使用的是相对路径,网站的入口文件目录为public,也就是说localhost/index.php/user写入之后要想将bootstrap资源引入,路径上需要用到两次‘…/’转到localhost(/public)目录下,之后在使用/static/js就能引入了。故而跳转edit.html,由于路径定向使用的相对路径,所以由于传递了依次id,被默认视为一级目录导致路径出错,由于是两种不同的路径,因此只能考虑使用绝对路径,修改为如下代码:

 'tpl_replace_string' => ['__JS__' => request()->domain().'/static/js','__CSS__' => request()->domain().'/static/css',]

解释:利用函数request()->domain()可以获取网站域名(也就是入口文件目录),这样就不必使用相对路径了。(补充说明一点:由于thinPHP6.0提供缓存,如果没有效果可以删除runtime/temp目录下的文件并刷新重试),设置完成后的页面展示如下:

展示部分就完成了,接下来就是数据修改部分的php实现了。

3.浏览器的cookie与session机制


    cookie,当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header)。

    当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,对于Windows操作系统而言,我们可以从: [系统盘]:\Documents and Settings[用户名]\Cookies目录中找到存储的Cookie(该文件属于受保护的文件,如果想要查看需要在查看的选项中去掉 ‘隐藏受保护文件’ 提高访问权限,不过不安全修改了权限记得改回来,浏览器其实也是可以查看cookie的);自此,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。

    cookie特点:cookie不可跨域名,不同的网站服务器向客户端颁发的cookie不一样。cookie保存中文使用Unicode编码,内存中占用4个字符。其次,cookie名称被创建后不可更改。由于每次用户访问网站会携带网站的cookie信息,因此cookie信息需要做到小而精。

    有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的。


    session是一次浏览器和服务器的交互的会话。

    session会话的来历:浏览器打开网页使用的是http协议,而相邻的两个http协议之间没有联系。但是有的时候,在同一网站下面的两个不同页面需要登录用户才能访问,这个时候两次要求用户两次输入密码显得不太合理。其初解决上述问题是采用cookie来解决的,但是cookie存储数据少、不安全等导致了session的诞生,由于session的存储量更大,可以用于保存页面的退出前状态,提高用户友好性。

session的工作原理:如上图所示,当浏览器第一次访问服务器时,服务器创建一session对象(该对象有一个唯一的id,一般称之为sessionId),服务器会将sessionId以cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据sessionId就可以找到对应的session对象。

 HttpSession s = request.getSession(boolean flag);

getSession函数的参数中,flag为true表示的是,先查看请求当中是否有sessionId,如果没有,则创建一个session对象。如果有,则依据sessionId 查找对应的session对象,如果找到了,则返回该对象,如果找不到,创建一个新的session对象。为false的话,只有当请求中存在sessionid才查找并返回session对象否则直接返回null。

session的特点:存储容量大,由于存在在服务器端,用于传递在客户端与服务器端的信息量被增大,加大了服务器的压力。

4.token令牌原理

    说到底,session终究还是cookie的一种优化,当浏览器禁用cookie时,二者都将失效,因此便诞生了当前比较流行、更为灵活的token令牌机制。但是token并不只是验证这一个作用,更胜一筹的是token优化了表单提交处理。

token的工作原理:和session有点相似,用户第一次登录网站提交用户名和密码,如果通过验证由服务器利用(用户唯一标识+网站设计者的秘钥),结合HMAC-SHA256 算法进行加密,这样能够更加安全,只要秘钥不丢失token伪造就几乎不可能,这样就能满足安全性和唯一性两大要求了。当然,至于token的加密和存储,很多博主也提到了对称加密,token存在解密过程,token直接使用mac地址(电脑唯一标识之一)或者sessionId(sessionId与token并不冲突)等,token存储在cookie或者Local Storage中等。不管是哪一种方法,在整体上表达的意思是:token诞生之后,服务器不在无脑存储session以及sessionId,存储的是一种验证算法,这种算法如果是堆成加密,那么token解密后得到的数据可以进行查询,如果是不可逆加密,两次token可用于鉴权(鉴权:是否登录或者说是使用网站api的权限)。

5.利用token防止表单重复提交

    接下来,我们回到thinkPHP修改用户数据上。一般我们会使用“返回修改”按钮回到edit.html页面,但是我们也可能会使用浏览器自带的返回,当我们使用浏览器自带按钮返回并提交表单时,实际数据是无效的,原因如下:
    在表单提交之后会生成一个token,该token存放在服务端的session或者cache中,并且后端会将该数据发一份给前端。在form表单中,页面使用一个隐藏表单域获取后端传过来的 token值,下一次便将该token再次传回到服务端,如果第二次生成的token与隐藏表单传值一致说明重复了,证明这是一次重复提交,将会像用户返回提示并终止后面的验证。
    实现起来也比较简单,在Validate/User.php中增加rule规则如下:

 '__token__' => 'require|token'

添加相应的规则并写入隐藏表单之后出现如下报错:

解决方法,在app/middleware.php文件中写入如下代码,开启session:

'think\middleware\SessionInit'

6.同步表单数据库修改

根据thinkPHP函数报错提示在controller/User.php中写入如下函数并打印表单提交参数:

  public function read(){}public function update(Request $request,$id){//        return '修改:'.$id;dd($request->param());}

得到如下效果:

    接下来就是密码验证了,下面给出场景验证的概念,这里肯定是想要重用Validate模块,但是Validate中本来有username,并设置了require,我们需要设置部分验证(相对于batch全部验证而言),在app/Validate/User.php写入如下代码:

protected $scene=['insert' =>['username','email','password','passwordnot','agree','__token__'],'edit'   =>['__token__','newpasswordnot']];

解释:挺好理解的,就是将上面写好的规则组成一个小的数组集合,形成一套验证方案,之后在Validate中直接调用选择好的验证方案名字就行。
    修改后的update方法如下(注意场景之后还需要写batch(true),表示验证场景内部所有规则):

$data=$request->param();try{validate(UserValidate::class)->scene('edit')->batch(true)->check($data);}catch(ValidateException $exception){return view('../view/public/toast.html',['infos' => $exception->getError(),'url_text' => '返回列表','url_path' => url('/user')]);}$id=UserModel::update($data)->getData('id');return $id ? view('../view/public/toast.html',['infos' => ['恭喜你,修改成功!'],'url_text' => '返回首页','url_path' => url('/user')]): '注册失败';

效果展示如下:

    如此大功告成!

参考文献:

    1.理解cookie与session机制

    2.session的到底是做什么的?

    3.什么是Session?

    4.Cookie和token的区别

    5.token防止表单重复提交,token 原理

    6.thinkphp6.0没有开启session

thinkPHP6.0入门笔记(四)——删除和修改用户信息相关推荐

  1. thinkPHP6.0入门笔记(七)——关联模型

    thinPHP6.0的关联模型及关联方法 1.一对一关联 1.1一对一关联查询 1.2一对一关联新增 1.3一对一关联删除 1.4一对一关联修改 2.一对多关联 2.1一对多关联模型常用方法 3.多对 ...

  2. Centos中用户相关操作(创建用户、设置密码、切换用户、修改用户信息、附加组、删除用户、用户分类)

    1.创建新用户 在root用户权限下新建用户: useradd -m xxx 选项 说明 -m 自动创建用户主目录,主目录的名字就是用户名 -g 指定用户所属的用户组,默认不指定会自动创建一个同名的用 ...

  3. java 银行管理系统怎么储存账户信息_银行管理系统 实现用户注册 登录 存、取款 交易记录查询和修改用户信息等功能...

    ========= 项    目   介   绍======== 银行账户管理系统 本项目主要实现用户注册 登录 存.取钱和修改用户信息功能. 用户信息的存储和获取通过集合和IO输入输出流实现. 存钱 ...

  4. jsp弹窗修改信息_WEB最最最初级修改用户信息

    哈喽,今天第一次发.内容非常非常基础,记录一下自己的成长吧. 今天的内容是通过jsp页面传参来修改用户信息.emmm,说的通俗一点就是对数据库的修改. 好! 话不多说!我们开始! 先看我简陋的页面 那 ...

  5. 用户中心 - 修改用户信息

    package com.leon.pojo.bo.center;import io.swagger.annotations.ApiModel; import io.swagger.annotation ...

  6. usermod 修改用户信息

    7.2 usermod 修改用户信息 1.命令功能 usermod 修改已存在的用户账号信息. 2.语法格式 usermod option login 参数选项说明 选项 选项说明 -c 修改用户pa ...

  7. VueJS ajax综合案例(修改用户信息实现步骤)

    修改用户信息 1.过程演示 2.代码实现

  8. linux修改用户描述的命令,Linux修改用户信息(usermod)

    Linux修改用户信息(usermod)教程 Linux usermod命令详解 功能 修改用户账户. 语法 usermod [options] username 参数 参数 描述 options u ...

  9. vue实现修改用户信息的全过程

    实现效果 具体实现步骤: 1.准备一个对话框,并在其中加入自己想要的表单,当点击修改按钮时,启用对话框 <!-- 修改用户的对话框--> <el-dialogtitle=" ...

最新文章

  1. 报告:AI技术正有效缩小亚洲医疗发展的差距
  2. 几种常用的加密方式简单介绍
  3. 【深度学习】编写同时在PyTorch和Tensorflow上工作的代码
  4. colinux php,利用colinux 搭建linux开发环境
  5. python_L2_operator
  6. ASP.NET 常见参考项目的 UI、BLL 、Model 、 DAL 分析
  7. 返回相同宽度数字型字符串
  8. 数据载入过慢?这里有一份TensorFlow加速指南
  9. msp430的常量可以这样定义
  10. 【git】基于github开源平台的项目进行二次开发
  11. 为什么我不给孩子看国产动漫?看看这5部法国动漫,你就知道了!【转】
  12. c++ 智能指针 (std::weak_ptr)(三)
  13. Android应用耗电问题排查
  14. 2021-2027全球与中国玻璃纤维网市场现状及未来发展趋势
  15. 小强IT游记之大连行
  16. Linux内核数据包格式
  17. 人工智能Java SDK:中文翻译为英文
  18. ADT和OOP自学,并撰写心得和收获。
  19. 零基础学画画,找对老师重要吗?
  20. 强烈推荐,分享一些让人拍案叫绝的黑科技软件(网站)

热门文章

  1. Fluorescein-PEG2k-Aminooxy在水中的溶解性比较好,FITC-PEG-Aminooxy
  2. webpack4打包传统H5多页面
  3. 无心剑中译叶芝《凡事皆可诱惑我》
  4. hashmap 缩容扩容_java面试必问——hashMap 深入分析put方法
  5. SVN解决冲突Resolving Conflicts
  6. 常见花材的固定的方法有哪些_干货贴|花材固定方法之基础篇
  7. C#版 - ZJNUoj1259 - 幸运数字——中高级 - 题解
  8. QQ农场启示录之:坐忘峰的盈利模式
  9. html首行字放大标签,CSS设置首字放大
  10. STM32的心率监测装置+OLED心率波形显示