# thinkphp6-shop **Repository Path**: hellowangming/thinkphp6-shop ## Basic Information - **Project Name**: thinkphp6-shop - **Description**: thinkphp6开发大型商城 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2024-10-12 - **Last Updated**: 2024-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # thinkphp6-shop000000 ## 1.tp6入门 ## 2.php行情分 ## 3.企业级开发流程和规范说明 ## 4.如何较好学习本套课程以及课程答疑指南 ## 5.基础环境安装 ## 6.Tp6框架源码获取(composer) ## 7.Nginx和PHP如何配合工作2 ## 8.如何高效的管理nginx配置文件 ## 9.TP5和TP6异同之处 ![image-20211204100722398](README_files/image-20211204100722398.png) ## 10.小白成长记-控制器巧用 ## 11.控制器巧用2-控制器request属性绑定request对象 ## 12.控制器巧用3-参数获取您知道TP有哪些方式吗? ## 13.健壮系统服务-杜绝无效请求 ### 1.当访问一个不存在的控制器或者方法,给出一个友好的提示 ![image-20211204104235560](README_files/image-20211204104235560.png) ![image-20211204104614630](README_files/image-20211204104614630.png) - **当用户访问控制器里面不存在的方法,会返回出错页面,这样的页面不友好,在basecontroller里面创建__call魔术方法,当访问不存在的方法时会返回提前定义好的数据格式** - ![image-20211204105808156](README_files/image-20211204105808156.png) - ![image-20211204105956719](README_files/image-20211204105956719.png) - **当控制器不存在的解决方法** - ![image-20211204110425341](README_files/image-20211204110425341.png) - ![image-20211204110439215](README_files/image-20211204110439215.png) - ## 14.简单事情极致化-通用化API数据格式数据 **简化上面的方法** - 在应用公共文件写一个返回的函数 - ![image-20211204111716923](README_files/image-20211204111716923.png) - 在__call方法处调用改函数 - ![image-20211204111817950](README_files/image-20211204111817950.png) - ![image-20211204112015340](README_files/image-20211204112015340.png) - ![image-20211204112024078](README_files/image-20211204112024078.png) ## 15.简单事情并不简单-通用化API数据格式数据优化 ### 2.由于一个项目中有很多状态码,所以数据格式返回函数里面的status状态码,单独抽离出来放在配置文件来处理 - ![image-20211204113518113](README_files/image-20211204113518113.png) - 现在把之前的状态码变量改回来 - ![image-20211204114047660](README_files/image-20211204114047660.png) - ![image-20211204114143700](README_files/image-20211204114143700.png) - ![image-20211204114153629](README_files/image-20211204114153629.png) ## 16.框架操作数据库-db库基础认知 ## 17.数据库操作-db查询方式讲 ## 18.数据库操作-非常适用的问题排查方案 ![image-20211204131651448](README_files/image-20211204131651448.png) ## 19.数据库操作-db其他操作场景 ## 20.模型初始 ## 21.模型查询其他使用讲解 ## 22.多应用模式 > 如果要使用多应用模式,你需要安装多应用模式扩展`think-multi-app`。 ``` composer require topthink/think-multi-app ``` ## 23.多应用模式下路由规则容易犯的错误 - 多应用模式下的路由访问,地址栏url必须带上模块名,在路由规则里面定义无效 ## 24.架构分层-初学者最容易犯的错误 ## 25.代码分层-模型内容抽 ## 26.基础架构分层思想-5层架构 ![image-20211204151429837](README_files/image-20211204151429837.png) ![image-20211204152159269](README_files/image-20211204152159269.png) ![image-20211204152458432](README_files/image-20211204152458432.png) ![image-20211204152628607](README_files/image-20211204152628607.png) ## 27.基础架构分层实战 ## 28.不可预知得内部异常处理1 - ![image-20211204153853460](README_files/image-20211204153853460.png) - ![image-20211204154403480](README_files/image-20211204154403480.png) - **这个场景适合api模块,而且属于公共模块下的异常处理** ## 29.不可预知得内部异常处理2 - 在模块下单独定义本模块的异常处理 - ![image-20211204155749770](README_files/image-20211204155749770.png) - ![image-20211204155824112](README_files/image-20211204155824112.png) - ![image-20211204155847025](README_files/image-20211204155847025.png) - ## 30.不可预知得内部异常处理3 - ![image-20211204161451346](README_files/image-20211204161451346.png) - ![image-20211204161506770](README_files/image-20211204161506770.png) ## 31.玩转中间件处理 - ![image-20211204162522481](README_files/image-20211204162522481.png) - ![image-20211204162614960](README_files/image-20211204162614960.png) - ![image-20211204162734463](README_files/image-20211204162734463.png) - ![image-20211204164233874](README_files/image-20211204164233874.png) - ## 32.电商需求梳理和分析 ## 33.需求分析-设计图 ## 34.需求分析-项目功能点输出 ![image-20211204170807618](README_files/image-20211204170807618.png) ![image-20211204170830347](README_files/image-20211204170830347.png) ## 35.需求分析-系统核心技术点梳理和分析 ## 36.本章功能分析 - ![image-20211204172419943](README_files/image-20211204172419943.png) - ![image-20211204172801853](README_files/image-20211204172801853.png) - ## 37.后端页面部署到项目服务器中 ![image-20211204174022297](README_files/image-20211204174022297.png) ## 38.登录页面配合模板引擎使 #### 模板输出替换 支持对模板文件输出的内容进行字符替换,定义后在渲染模板或者内容输出的时候就会自动根据设置的替换规则自动替换。 如果需要全局替换的话,可以直接在配置文件中添加: ``` 'tpl_replace_string' => [ '__STATIC__'=>'/static', '__JS__' => '/static/javascript', ] ``` > 替换规则严格区分大小写 ![image-20211204175334281](README_files/image-20211204175334281.png) ![image-20211204182549717](README_files/image-20211204182549717.png) ## 39.后端用户表设计 ```mysql /* Navicat MySQL Data Transfer Source Server : 127.0.0.1 Source Server Type : MySQL Source Server Version : 80019 Source Host : localhost:3306 Source Schema : mall Target Server Type : MySQL Target Server Version : 80019 File Encoding : 65001 Date: 02/06/2020 19:43:09 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for mall_admin_user -- ---------------------------- DROP TABLE IF EXISTS `mall_admin_user`; CREATE TABLE `mall_admin_user` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '后端用户主键ID', `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名', `password` char(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户密码', `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '状态码 1正常 0待审核,99删除', `create_time` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', `last_login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '最后登录时间', `last_login_ip` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '最后登录IP', `operate_user` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '操作人', PRIMARY KEY (`id`) USING BTREE, KEY `username` (`username`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; SET FOREIGN_KEY_CHECKS = 1; ``` ## 40.TP6内置验证码引入到登录页面中 - 安装验证码组件 - ` composer require topthink/think-captcha` - 验证码大小调整 - ![image-20211204191613788](README_files/image-20211204191613788.png) - ![image-20211204191644604](README_files/image-20211204191644604.png) - ## 41.如何处理自定义验证码 - ![image-20211204192226001](README_files/image-20211204192226001.png) - ![image-20211204192540272](README_files/image-20211204192540272.png) - ![image-20211204192652103](README_files/image-20211204192652103.png) - ![image-20211204193155768](README_files/image-20211204193155768.png) - ## 42.后端登录-ajax方式登录 - **先模拟登陆,走通流程** - ![image-20211204193735284](README_files/image-20211204193735284.png) - ![image-20211204200030315](README_files/image-20211204200030315.png) - ![image-20211204200052429](README_files/image-20211204200052429.png) ## 43.ajax登录-基本参数校验(普通方式校验) ## 44.后端用户登录API逻辑开 ![image-20211204222700397](README_files/image-20211204222700397.png) ![image-20211204222734665](README_files/image-20211204222734665.png) ## 45.后台用户登录-数据更新和session处理 ```php request->isPost()) { return show(config('status.error'), '请求方式错误!'); } //参数校验 1.原生方式 2.tp6验证机制 $username = $this->request->param('username', '', 'trim'); $password = $this->request->param('password', '', 'trim'); $captcha = $this->request->param('captcha', '', 'trim'); if (empty($captcha) || empty($username) || empty($password)) { return show(config('status.error'), '参数不能为空!'); } //验证码校验,需要在模块中间件开启session if (!captcha_check($captcha)) { //验证码校验失败 return show(config('status.error'), '验证码错误!'); } try { //调用模型查询该用户数据 $obj = new AdminUser(); $result = $obj->getAdminUserByUsername($username); if (empty($result) || $result->status != config('status.mysql.table_normal')) { return show(config('status.error'), '不存在该用户!'); } $result = $result->toArray(); //判断密码是否与输入的一致 $tabPass = $result['password']; if ($tabPass !== md5($password . '_singwa_abc')) { return show(config('status.error'), '用户名或者密码错误!'); } //需要记录信息到mysql中 $updateData = [ 'last_login_time' => time(), 'last_login_ip' => $this->request->ip(), 'update_time' => time() ]; $res = $obj->updateById($result['id'], $updateData); if (empty($res)) { return show(config('status.error'), '登录失败!'); } } catch (\Exception $e) { // todo 记录日志 $e->getMessage(); return show(config('status.error'), '内部异常,登录失败!'); } //把登录信息加入session session(config('admin.session_admin'), $result); return show(config('status.success'), '登录成功!'); } } ``` ## 46.你确定你知道了登录的流程走势 - ![image-20211205082424352](README_files/image-20211205082424352.png) - ## 47.按base方式处理登录流 ## 48.利用后置中间件处理登录流-拦截器 ## 49.利用前置中间件处理登录流-拦截器 ## 50.登录优化-引入validate验证机制) ## 51.登录优化-控制器业务代码抽离到business层 ## 52.商城前端用户模块开发准备工作的介绍 ## 53.商城前端用户表设计 ## 54.阿里云短信介绍以及sdk获取 ```php 'dysmsapi.aliyuncs.com', 'access_key_id'=>'****************', 'access_key_secret'=>'***************', 'region_id'=>'cn-hangzhou', 'template_code'=>'SMS_204103704711',//短信模板id 'sign_name'=>'签名名称',//签名名称 ]; ``` ```php $code ]; AlibabaCloud::accessKeyClient(config('aliyun.access_key_id'), config('aliyun.access_key_secret')) ->regionId(config('aliyun.region_id')) ->asDefaultClient(); try { $result = AlibabaCloud::rpc() ->product('Dysmsapi') // ->scheme('https') // https | http ->version('2017-05-25') ->action('SendSms') ->method('POST') ->host(config('aliyun.host')) ->options([ 'query' => [ 'PhoneNumbers' => $phone, 'SignName' => config('aliyun.sign_name'), 'TemplateCode' => config('aliyun.template_code'), 'TemplateParam' => json_encode($data) ], ]) ->request(); // Log::info("alisms-sendCode-result".json_encode($result->toArray())); // print_r($result->toArray()); } catch (ClientException $e) { return false; // echo $e->getErrorMessage() . PHP_EOL; } catch (ServerException $e) { return false; // echo $e->getErrorMessage() . PHP_EOL; } return true; } } ``` ## 55.lib库下发送短信验证码类库封装 ## 56.发送短信验证码API逻辑编写以及布置的作业 ## 57.短信验证码记录到redis中 ```php if($sms){ //需要把验证码记录到Redis,并且给出一个失效时间 cache(config('redis.code_pre_').$phoneNumber,$code,config('redis.code_expire')); } ``` ## 58.剔除common公共方法思想以及新思想引入做到代码高度可维护和管理 ```php 'app\common\lib\sms\AliSms', 'baidu' => 'app\common\lib\sms\BaiduSms', 'jd' => 'app\common\lib\sms\JdSms', ]; } public static function upLoadClassStat(){ return [ 'text'=>'xxx', 'image'=>'xxx' ]; } public static function initClass($type, $classs, $params = [], $needInstance = false) { //1.如果我们工厂模式调用的方法时静态的.就返回类 //2.如果不是静态的,就返回对象 if (!array_key_exists($type,$classs)){ return false; } $className = $classs[$type]; //new ReflectionClass('A')=>建立A 反射类 //->newInstanceArgs($args)=>相当于实例化A对象 return $needInstance == true ? (new \ReflectionClass($className))->newInstanceArgs($params):$className; } } ``` ```php request->param('phone_number', '', 'trim'); $code = input('param.code', 0, 'intval'); $type = input('param.type', 0, 'intval'); //参数校验 $data = [ 'phone_number' => $phoneNumber, 'code' => $code, 'type' => $type, ]; $validate = new \app\api\validate\User(); $res = $validate->scene('login')->check($data); if (!$res) { return show(config('status.error'), $validate->getError()); } //调用business层做判断 $result = (new User())->login($data); if ($result) { return show(config('status.success'), $result); } return show(config('status.error'), '登录失败'); } } ``` ```php userObj = new UserModel(); // } public function login($data) { $redisCode = cache(config('redis.code_pre') . $data['phone_number']); if (empty($redisCode) || $redisCode != $data['code']) { throw new \think\Exception('验证码不存在', -1009); } //需要去判断表 是否有用户记录 $usermodel = new UserModel(); $user = $usermodel->getUserByPhoneNumber($data['phone_number']); //如果没有该手机号码,说该用户不存在,需要新增用户 if (!$user) { $username = 'fendou-' . $data['phone_number']; $userData = [ 'username' => $username, 'phone_number' => $data['phone_number'], 'type' => $data['type'], 'status' => config('status.mysql.table_normal'), ]; try { $usermodel->save($userData); $userId = $usermodel->id; } catch (\Exception $e) { throw new Exception('数据库内部异常'); } } else { //更新表 $userId = $user->id; $username = $user->username; } //生成token $token = Str::getLoginToken($data['phone_number']); $redisData = [ 'id' => $userId, 'username' => $username ]; $res = cache(config('redis.token_pre') . $token, $redisData, Time::userLoginExpiresTime($data['type'])); return $res ? ['token' => $token, 'username' => $username] : false; } } ``` ```php trim($phoneNumber) ]; $result = $this->where($where)->find(); return $result; } } ``` ```php