day3
修改操作
//save方法
//先查询再修改
$goods=\app\admin\model\Goods::find(32);
$goods -> goods_price ='123.00';
$goods -> goods_number = 321;
$res1 =$goods->allowField(true)->save();
dump($res1);
//返回一个1 代表修改了一条
//(推荐)静态update方法 修改数据 修改条件 过滤非数据表字段
\app\admin\model\Goods::update(['goods_price'=>'123.00','goods_number'=>321,'id'=>33],[],true);
\app\admin\model\Goods::update(['goods_price'=>'123.00','goods_number'=>321,'id'=>33],['id'=>33],true);
$res2 =\app\admin\model\Goods::update(['goods_price'=>'123.00','goods_number'=>321],['id'=>33],true);
dump($res2);
//返回的是数据库模型对象
//底层Db的update方法 (通过where方法后使用update方法
//通过where方法 返回的是修改条数
//单个修改
$res3 = \app\admin\model\Goods::where('id',34)->update(['goods_price'=>'123.00','goods_number'=>321]);
dump($res3);
//批量修改
$res4 = \app\admin\model\Goods::where('id','>=',53)->update(['goods_price'=>'123.00','goods_number'=>321]);
dump($res4);
区别返回值不同 模型的update方法 和底层update(where)方法区别
1.返回值不同,模型返回模型对象,底层返回修改条数
2.包含的功能不同 模型的update有过滤非数据表字段功能 底层的没有
只有静态方法可以过滤非数据表字段
save方法既可以做添加方法也可以做修改方法,在于传来的值是否有主键ID
手动判断save是否更新
$user= User::get(1);
$user->name = 'thinkphp';
//显示指定当前操作为新增操作
$user->isUpdate(false)->save();
删除操作
先查询,在调用模型delete方法删除
$user = User::get(1);
$user -> delete();
先调用where方法,在调用Query类的delete方法删除
User::where('id',1)->delete();
静态调用 destroy 方法删除(推荐)
User::destroy(1);
User::destroy('1,2,3');
User::destroy([1,2,3]);
User::destroy(['status'=>1]);
例子
//查询并删除(调用模型的delete方法)
//Goods返回的是一个对象
$goods = \app\admin\model\Goods::find('41');
$res =$goods->delete();
dump($res);
dump($goods);
$goods = \app\admin\model\Goods::find('41');
//Call to a member function delete() on a non-objec
//先查询后删除 如果没有查询到数据 会报错 查询到的是一个对象 查询为空会返回NULL
//需要使用empty判断是否为空
if(empty($goods)){
echo "数据已经不存在了";die;
}
$res =$goods->delete();
dump($res);
//通过where指定条件 再调用Query对象的delete方法
//where返回的是db对象 如果查询没有结果 删除delete的时候 显示int(0) 影响0条
$res =\app\admin\model\Goods::where('id','42')->delete();
dump($res);
//destroy方法 返回int(1) 括号里显示影响条数
$res = \app\admin\model\Goods::destroy('38');
dump($res).("=============");
$res = \app\admin\model\Goods::destroy('39,40');
dump($res).("=============");
$res = \app\admin\model\Goods::destroy([36,47]);
dump($res).("=============");
$res = \app\admin\model\Goods::destroy(['goods_price'=>'0.01']);
dump($res).("=============");
注意点使用delete方法 必须先查询是否有这个数据,如果没有会报错。所以需要多加一层判断
Traits
trait 是一种为类似 PHP 的单继承语言而准备的代码复用机制。trait
为了减少单继承语言的限制,使开发人员能够自由的在不同层次结构内独立的类中复用方法集。trait
和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类 ( mixin ) 相关的典型问题
trait A{
public function getName()
{
return "this is trait";
}
}
class B{
use A;
}
$b = new B();
echo $b->getName(); //This is trait
只有class可以被实例化 trait不能被实例化,没有实例化方法
注意点有同名的方法,当前类方法会覆盖 trait方法会覆盖继承类的方法
优先级 自己的类方法>trait方法>继承的父类方法
TP中的trait
父类控制器Controller中使用了Jump这个trait,提供了页面跳转相关方法
模型的softDelete这个trait,需要在自定义模型中,手动使用,提供的软删除相关功能
软删除
物理(硬)删除:真删除,从数据表直接删除记录。
逻辑(软)删除:假删除(本质是修改操作),只是让数据在页面不显示,数据表中仍然保留。
原理:在数据表添加一个字段控制数据在页面的展示。点击删除操作时,修改对应字段的值。
use traits\model\SoftDelete;
use SoftDelete;
use \traits\model\SoftDelete;
protected $deleteTime = 'delete_time';
只要加上了上面的内容 默认情况下就是软删除
//删除操作 软删除\app\admin\model\Goods::destroy($id);//真删除\app\admin\model\Goods::destroy($id,true);$goods= \app\admin\model\Goods::find($id);if(empty($goods)){ $this->error("数据已经不存在了");}//软删除$goods->delete();//真删除$goods->delete(true);//默认情况下删除成功跳转到当前页面 也就是列表页$this->success("删除成功");
day3下午
id参数检测
//id参数检测//大于0的整数if(!is_numeric($id) || $id===((int)$id) || $id<=0){ $this->error("参数错误");}if(!preg_match('/^\d+$/',$id) || $id==0){ $this->error("参数错误");}
密码加密函数
双重md5加密 外层md5加密加点盐 salt得固定 不然下次生成不一样
if(!function_exists('encrypt_password')){ //密码加密函数 function encrypt_password($string){ //加盐 得固定 php.拼接 $salt = 'gougeniubi'; return md5(md5($string).$salt); }}
Request-cookie-session
模板中使用
$Request.方法名.参数
{$Request.get.id}{$Request.param.name}
public function test_session(){ //设置 session('username','admin'); dump(session('username')); dump(session('?username')); //删除单个 session('username',null); dump(session('username')); //删除所有 session(null); //数组的用法 session('user',['id'=>1,'username'=>'admin']); dump(session('user.username')); session('user.email','admin@qqzmly.com'); dump(session('user')); /* string(5) "admin" array(3) { ["id"] => int(1) ["username"] => string(5) "admin" ["email"] => string(12) "admin@qqzmly.com" } */ session('user.email',null); dump(session('user')); //cookie cookie('name','zhangsan',3600); dump(cookie('name'));}
登录功能
//登录public function login(){ //一个方法 处理两个业务逻辑 页面展示 表单提交 if(request()->isPost()){ //表单提交 post请求 //接收参数 查询管理员用户表 //接收参数 username password code $params = input(); //参数检测 表单验证 $rule = [ 'username|用户名' =>'require', 'password|密码' =>'require', 'code|验证码'=>'require' ]; $res = $this->validate($params,$rule); if(true!==$res){ $this->error($res); } $password = encrypt_password($params['password']); //第一种写法两个where去查找 //$manager = \app\admin\model\Manager::where('username',$params['username']) // ->where('password',$password)->find(); //第二种批量查询 $manager = \app\admin\model\Manager::where(['username'=>$params['username'],'password'=>$password])->find(); //where查询会返回影响条数 if($manager){ //登录成功 设置登录标识到session中 session('manager_info',$manager->toArray()); //页面跳转 $this->success('登录成功','admin/index/index'); }else{ //登录失败 $this->error('用户名或密码错误'); } }else{ //get请求 页面展示 //临时关闭全局模板布局 $this->view->engine->layout(false); return view(); }}
退出功能
public function logout(){ //清空session session(null); $this->redirect('admin/login/login');}
登录检测功能
新建一个控制器
php think make:controller admin/Base --plain
Base控制器使用构造方法 其他的控制器继承Base Login登录页面不继承
class Base extends Controller{ public function __construct(Request $request = null) { //构造方法 实现父类的构造函数 parent::__construct($request); //登录检测 if(!session('?manager_info')){ //没登录 $this->redirect('admin/login/login'); } }}
验证码
没有安装THINKPHP自带的captcha就去安装 去项目根目录安装
composer require topthink/think-captcha=1.* 删除composer remove topthink/think-captcha 拓展composer require tp5/captcha
'captcha' => [ // 验证码字符集合 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', // 验证码字体大小(px) 'fontSize' => 25, // 是否画混淆曲线 'useCurve' => true, // 验证码图片高度 'imageH' => 30, // 验证码图片宽度 'imageW' => 100, // 验证码位数 'length' => 5, // 验证成功后是否重置 'reset' => true],
点击图片换验证码
onclick="this.src='{:captcha_src()}?'+Math.random()"
字符串拼接一个随机数 这样避免同一地址资源文件 浏览器有缓存不去加载
验证码显示
<div>{:captcha_img()}</div><div><img src="{:captcha_src()}" alt="captcha" /></div>
控制器验证
使用TP5的内置验证功能,添加captcha
验证规则即可
$this->validate($data,[ 'captcha|验证码'=>'require|captcha']);
或者手动验证
if(!captcha_check($captcha)){ //验证失败};//手动验证码校验if(!captcha_check($params['code'])){ $this->error('验证码错误');}
总结
1.修改操作以及后台商品修改功能(save方法、saveAll方法、静态update方法)
2.删除操作(delete方法、destroy方法)与软删除功能、trait
3.cookie 和 session 操作 (助手函数)
4.登录模块功能 (登录、退出、登录检测)
5.验证码( captcha_src() captcha_img() captcha_check() )
作业
1.商品修改、商品删除(软删除)、登录、退出、登录检测、验证码
2.管理员模块增删改查
注意点:
管理员列表:不显示密码
管理员添加:不做角色 用户名、密码(加密)、邮箱、昵称等
管理员修改:用户名不能修改 ,可以改密码(重置别人的密码)、邮箱、昵称等
管理员删除:不能删除admin管理员
修改密码 (修改自己的密码)