<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                json() 提供 方法 修改 開啟報錯查看 ![](https://img.kancloud.cn/0c/90/0c9007f59b7ad18eeefe50fc4238e4ff_196x109.png) ## env 中開啟 de\_bug database配置數據庫 會先使用 .env 中的配置! ![](https://img.kancloud.cn/ee/ad/eead3bc36f4c4c5fafb7666be0f5d46c_885x660.png) ![](https://img.kancloud.cn/39/95/399564537aa41bef8a6697a4a2fd28c8_459x495.png) tp6 中使用 **Db**:: 需要 use 門面模式 user think\\facade/\\Db ![](https://img.kancloud.cn/b5/7c/b57cde7c1e3dd0ba472045914387d9b9_1073x294.png) ## app.php config/app.php 錯誤信息 ## 多應用模式 ``` composer require topthink/think-multi-app ``` 在當前控制器下創建 route 路由文件夾 配置域名訪問 http://www.tp6.com/demo.php/index/test?a=1 在public 下復制index.php 改名為 demo.php $response = $http->name(‘demo’)->run(); 若是文件名不同 可用 name指向 config 可以在每個 目錄下 + admin / config 當前目錄有用 api/config … ## 路由 多應用 需要 加 文件名 admin/text index/… ## config 下 業務狀態碼 創建 status.php` return \[ ‘success’ => 1, ‘error’ => 0, \]; 未開啟強制路由 都可以 http://www.tp6.com/index.php/demo/index/t demo 應用 inde想控制器 t方法 http://www.tp6.com/demo.php/index/t ![](https://img.kancloud.cn/b7/07/b707c6984f257935eca4e4625cfe7788_1018x521.png) ![](https://img.kancloud.cn/2a/42/2a42dbffa035fae58125f5760e476801_926x407.png) ## has 判斷某個值是否設置 ## 容器和依賴注入 ![](https://img.kancloud.cn/3b/5a/3b5a3ab7606f10135a50ec4d200454c0_654x276.png) ![](https://img.kancloud.cn/d4/b7/d4b7603cc4f8e8488f67df688518e459_368x390.png) ## 全局中間件 可以通過命令行指令快速生成中間件 php think make:middleware Check ~~~ <?php namespace app\middleware; class Check { public function handle($request, \Closure $next) { // 添加中間件執行代碼 ... return $next($request); } } ~~~ 在 app/middleware.php ~~~ <?php // 全局中間件定義文件 return [ // 全局請求緩存 // \think\middleware\CheckRequestCache::class, // 多語言加載 // \think\middleware\LoadLangPack::class, // Session初始化 // \think\middleware\SessionInit::class app\middleware\Check::class, ]; ~~~ ## 應用中間件 ![](https://img.kancloud.cn/89/f2/89f28316c52f626c45143d902170f7b8_302x378.png) ## 模板引擎 composer安裝 ![](https://img.kancloud.cn/1e/ad/1eadbadf346ddd4716c0c47f6de043e3_1106x700.png) ``` composer require topthink/think-view ``` ## 簡單的密碼+鹽處理 密碼 123 md5(‘123\_md5’) 處理字符串 ## 驗證碼 ``` composer require topthink/think-captcha ``` ![](https://img.kancloud.cn/a0/aa/a0aa90a524ece726e29d54f48b01bb8b_1851x1080.png) ![](https://img.kancloud.cn/4e/9e/4e9ed419d414fdb8f7bf8a78f927f6f0_1089x236.png) 驗證碼使用 驗證是時 徐快需要在中間件中開啟session! ![](https://img.kancloud.cn/54/3e/543eac0212132ea796af2bdc73167085_1851x1080.png) ## 模型分層架構 ![](https://img.kancloud.cn/12/78/1278c00aeef4e02ce8fd4937ef5a0c1d_1306x521.png) 思維 ## 驗證器 ~~~ $data = [ 'username' => $username, 'password' => $password, 'captcha' => $captcha, ]; $validate = new \app\admin\validate\AdminUser(); if(!$validate->check($data)) { return show(config("status.error"), $validate->getError()); } ~~~ ~~~ <?php /** * Created by singwa * User: singwa * motto: 現在的努力是為了小時候吹過的牛逼! * Time: 07:11 */ namespace app\admin\validate; use think\Validate; class AdminUser extends Validate { protected $rule = [ 'username' => 'require', 'password' => 'require', 'captcha' => 'require|checkCapcha', ]; protected $message = [ 'username' => '用戶名必須,請重新輸入', 'password' => '密碼必須', 'captcha' => '驗證碼必須', ]; protected function checkCapcha($value, $rule, $data = []) { if(!captcha_check($value)) { return "您輸入的驗證碼不正確!"; } return true; } } ~~~ ## Url 注意 ![](https://img.kancloud.cn/e6/15/e615c34cdf3dfbc35db4ea0d9f62b741_557x165.png) ## 如何正確分層之操作datebase ## 注意使用 init初始化 ## 如何處理在init里無法重定向 ![](https://img.kancloud.cn/83/c0/83c0606e76437160937177719eea752b_1851x1080.png) ## 注意 如何 /admin/index/index 寫的時候需要+ /’ ## 前置中間件 ![](https://img.kancloud.cn/4d/de/4ddedaf37985db4e6bbaab15ad8689f7_1851x1080.png) preg\_match() 1 正則 2 str 匹配2中有無 1 return 1 0 ## 后置中間件 ![](https://img.kancloud.cn/f9/10/f910186efb51f5a31788f97233776d80_789x735.png) ## session ~~~ session('adminUser', $res); session('adminUser', null); ~~~ * 1 ## business 業務邏輯層 在business 處理業務邏輯 -> 調用 model 的sql執行 在business進行 異常拋出 在c層try catch 補獲 model 放在 common 公共文件里 ![](https://img.kancloud.cn/d8/be/d8be27a60a09cb14a946e5b53725a2fd_1851x1080.png) ## redis 實現驗證碼 存活時間60s 安裝 https://blog.csdn.net/kxukai/article/details/106692983 ## 日志 開啟日志 runtime 可以查看執行的原生sql語句 進行分析 ![![](https://img.kancloud.cn/d8/be/d8be27a60a09cb14a946e5b53725a2fd_1851x1080.png)](images/screenshot_1653443315790.png) ## 工廠模式 ![](https://img.kancloud.cn/21/08/2108d204a41d287191e7460f13dcf0cc_1850x1080.png) ![](https://img.kancloud.cn/da/56/da565da7d763838acef7e3260b8f689c_1850x1080.png) ![](https://img.kancloud.cn/23/e1/23e1f0e4616fd9cb9b87d27be00f1346_1850x1080.png) 短信可以使用redis 進行限制 存手機號 + 發信息間隔時間~ ## 如何流控 20%阿里云短信 80%百度云短信 案例:2018年年底 央視春晚 百度手機號登錄發送驗證碼分發不同運營商流量, 就是用這個來做的, 并發50萬 發送短信驗證碼。 簡單粗暴 實用 最簡單的方法往往最有效 ~~~ $a = rand(0,99); if($a < 80) { // 阿里云邏輯 } else { // 百度云邏輯 } ~~~ ## 前后端分離 redis+ token 不使用session+cookie ## config(‘statis.success’) ![](https://img.kancloud.cn/27/86/278635f2adffa5b34a7b9ca052a25e43_475x395.png) ## 異常處理 try catch 捕獲異常時 注意記錄日志 以供分析 tp6 helper 全局搜索自帶拋出異常 throw\_if 同laravel 手動拋出異常 ~~~ throw new \think\Exception("不存在該驗證碼", config('status.code.not_code')); ~~~ * 1 捕獲異常 ~~~ try { $result = (new \app\common\business\User())->login($data); } catch (\Exception $e) { return show($e->getCode(), $e->getMessage()); } ~~~ // 阻止數據庫拋出異常 被 用戶看到 手動拋出~ ~~~ try { $this->userObj->save($userData); $userId = $this->userObj->id; }catch (\Exception $e) { throw new \think\Exception("數據庫內部異常"); } ~~~ ![](https://img.kancloud.cn/2f/ee/2feece55d1a07376a775a1a7cfffa41a_1851x1080.png) ## redis 刪除 等于null 即可 ## redis 寫登錄 邏輯 前后端分離 所以是 api 接口 1. 用戶點擊發送驗證碼 把 sms . 手機號 存入 redis 內容有 驗證碼 存活60s //這里sms為了再redis中進行區分別的緩存 2. 接收數據 轉換格式 驗證 isajax ispost ~~~ if (!$this->request->isPost() || !$this->request->isAjax() ) return show(config("status.error"), "非法請求"); $phoneNumber = input("phone_number",'','trim'); $code = input("code", 0, "intval"); ~~~ 3. validate 驗證器 驗證參數 4. 驗證 用戶輸入的 code !== redis中的該手機號對應的 code ~~~ // 用戶輸入的 code !== redis中的該手機號對應的 code $redisCode = cache(config("redis.code_pre") . $data['phone_number']); if (empty($redisCode) || $redisCode != $data['code']) { throw new \think\Exception("不存在該驗證碼", config('status.code.not_code')); } ~~~ 從第五層開始要在 business 邏輯層進行處理 判斷 例子 拋出異常最好用 try catch 進行補獲 避免數據庫拋出暴露信息被用戶查看 ![](https://img.kancloud.cn/4c/a3/4ca31f6f7c8d6d7e08df08dbf039e87f_1851x1080.png) 5\. 還是在common/ business 操作 根據用戶手機號 查找有該用戶登錄記錄 ~~~ // 需要去判斷表 是否有 用戶記錄 phone_number // 生成token $user = $this->userObj->getUserByPhoneNumber($data['phone_number']); ~~~ 這里model 層在 common/model datebase 操作公共的 可以共用 ![](https://img.kancloud.cn/f2/b6/f2b618a9d4fb46ea7132573341cce74f_574x296.png) 然后進行判斷 操作用戶記錄 ![](https://img.kancloud.cn/a7/14/a71433e0a3f3640d8a3b18f247815495_701x570.png) 6\. 然后把生成的token作為k 用戶的id 和用戶名作為 v 存入redis 存活時間 ~ ~~~ $redisData = [ "id" => $userId, "username" => $username, ]; $res = cache(config("redis.token_pre") . $token, $redisData, Time::userLoginExpiresTime($data['type'])); ~~~ 7.最后把前端需要的數據返回 ## 中間件 進行 前端 檢測是否登錄 2種方法 第一種方法 需要驗證login的controller extends 該控制器 進行檢測 ~~~ class AuthBase extends ApiBase { public $userId = 0; public $username = ""; public $accessToken = ""; public $isLogin = 1; public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub // if ($this->isLogin == 1) { // $this->userId = 6; // 測試場景 // return true; // } $this->accessToken = $this->request->header("access-token"); if (!$this->accessToken || !$this->isLogin()) { return $this->show(config("status.not_login"), "沒有登錄"); } } /** * 判斷用戶是否登錄 * @return bool */ public function isLogin() { $userInfo = cache(config("redis.token_pre") . $this->accessToken); if (!$userInfo) { return false; } if (!empty($userInfo['id']) && !empty($userInfo['username'])) { $this->username = $userInfo['username']; $this->userId = $userInfo['id']; return true; } return false; } } ~~~ 第二種方法使用中間件 進行檢測 在api 文件下 創建一個 ![](https://img.kancloud.cn/6e/c6/6ec69c3a1f816ea28fc424a2b0231d22_523x570.png) 修改 middlevare.php 中 對應信息 ~~~ <?php declare (strict_types=1); namespace app\api\middleware; class Auth { /** * 處理請求 * * @param \think\Request $request * @param \Closure $next * @return Response */ public function handle($request, \Closure $next) { //前置中間件 // if (empty(session('adminUser')) && !preg_match("/login/", $request->pathinfo())) { // return redirect((string)url('login/index')); // } //ajax 返回api格式 例如處理rbac //這樣會處理所有api下的控制器 所以需要 // return $this->show(config("status.not_login"), "沒有登錄"); if (in_array($request->pathinfo(), config('login.need_verify_login'))) if (!$this->isLogin()) return ajaxReturn(0, '', '未登錄,請先登錄'); return $next($request); } public function end(\think\Response $response) { } /** * 判斷用戶是否登錄 * @return bool */ public function isLogin() { $token = request()->header("access-token"); $userInfo = cache(config("redis.token_pre") . $token); if (!$userInfo) { return false; } if (!empty($userInfo['id']) && !empty($userInfo['username'])) { return true; } return false; } } ~~~ ## 免登錄 打開登錄界面 前 執行控制器 的 中間件 進行 驗證 獲得返回數據 進行 重定向至跳轉首頁 or 等待用戶登錄 ##退出登錄 清空當前redis中 k 拼接 對應的token v 為 null ![](https://img.kancloud.cn/aa/f1/aaf15929fd635a738c52016a46b4775a_1174x404.png) ## model 層代碼優化 business 邏輯層?! ![](https://img.kancloud.cn/33/f7/33f78f9c524360383688d951b6f02653_1003x630.png) model 層![](https://img.kancloud.cn/ff/83/ff835a3a3e362e06d4d55abcc9fe7252_1150x518.png) 這里可以父類繼承 調用 減少代碼量 ![](https://img.kancloud.cn/c1/18/c118236b54088a2b283e75731b41a5f1_1851x1080.png) ## 面向過程 => 面向對象 統一返回給前端 ![](https://img.kancloud.cn/be/e5/bee571a2d1d8217d2a80380ff7dbd85a_1920x1051.png) ## 模型 使用 ![](https://img.kancloud.cn/35/4c/354cc5e31561dd186d7eb954c9fb0475_1138x356.png) with 會?`兩次`執行sql語句 進行查詢 數據量大 大公司常用 withjoin 一次join 查詢 ## sku 建議用2 方便 直接對應sku表的id 統一規格也使用 sku ![](https://img.kancloud.cn/8b/3b/8b3b440c434659ec6475445c5a28ab72_1066x479.png) ## 系統瀏覽量 pv 每個商品的瀏覽量 ![](https://img.kancloud.cn/a7/72/a77279101a4a8859f69b7a0e4582b564_866x202.png) ## 商品展示流程 展示商品有自己默認skuid ![](https://img.kancloud.cn/94/08/9408a809ad89a3107b74b4db17436767_893x633.png) 用戶點擊根據skuid 到sku查詢到 該商品的goodsid 然后根據goodsid 到goods 獲取該商品信息 和 該商品對應的 所有 sku信息 ![](https://img.kancloud.cn/5b/97/5b979c0639c18009b53904d2a5157be0_736x412.png) ![](https://img.kancloud.cn/82/58/82585a710f1162734df4ee6aaf67a804_721x277.png) 這里gids 1,11 :1 : 1 //skuid 1, 11 規格id // 顏色, 尺碼 ![](https://img.kancloud.cn/1f/e2/1fe2ea2668cdea95d3d3a82d7aa58f26_355x174.png) ![](https://img.kancloud.cn/3a/00/3a00791acdb9c137357ee2db1f1b18ec_268x371.png) ![](https://img.kancloud.cn/b0/c8/b0c8cd1c9c7671fff4c936a51fceb1b7_1177x665.png) sku ![](https://img.kancloud.cn/23/6e/236e291e7ecfad891de0a843a8d3054b_347x561.png) ## 購物車 瀏覽器緩存 mysql redis 存redis 高性能 hash 表如何設計的 流程 1.加入購物車 用戶登錄狀態 點擊商品加入購物車 即加入redis 中 (1) 到mysql根據skuid查找該商品的sku數據 2.購物車展示頁面 3.購物車刪除 修改數量 4.購物車排序 ![](https://img.kancloud.cn/4b/0d/4b0d6d28010f5914872adc025cf27d37_1920x1051.png) ![在這里插入圖片描述](https://img-blog.csdnimg.cn/2020062411424451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t4dWthaQ==,size_16,color_FFFFFF,t_70) ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20200624114310976.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t4dWthaQ==,size_16,color_FFFFFF,t_70) 封裝在基礎類庫 hgetall ![](https://img.kancloud.cn/97/55/97551e20b850e54f0e8b470fa53214cb_1037x709.png) 刪除 hdel test 1 2 ![](https://img.kancloud.cn/17/e5/17e5243b70884df6b208f8ff249f29ac_842x471.png) 獲取redis 購物車數據 進行排序 ![](https://img.kancloud.cn/3f/f3/3ff363dc9a276dff49e83d59678527dc_795x217.png) hLen 獲取數據 返回值 integer-reply: 哈希集中字段的數量,當 key 指定的哈希集不存在時返回 0 例子 redis> HSET myhash field1 “Hello” (integer) 1 redis> HSET myhash field2 “World” (integer) 1 redis> HLEN myhash (integer) 2 redis> ## 庫存 嚴謹判斷 購物車+ 訂單 未支付 …2 hMget 返回 key 指定的哈希集中指定字段的值。 對于哈希集中不存在的每個字段,返回 nil 值。 hGetAll 返回 key 指定的哈希集中所有的字段和值。 ![](https://img.kancloud.cn/a3/b7/a3b7792b6171c85788c6b2c3bf48e2d3_1071x519.png) ![](https://img.kancloud.cn/17/00/17005dbfaf8e1f54de8de31de9bbf38d_1371x485.png) 訂單 主表副表!![](https://img.kancloud.cn/e6/e8/e6e878f30421a1b7f43865cb270c51ef_1422x535.png) ![](https://img.kancloud.cn/91/6a/916afebb43cc0478c1d8bea810cab10e_1138x298.png) ## 訂單流程 進入 加入 購物車頁面 訂單確認頁面 和 提交訂單頁面 都需要判斷?`庫存` 提交訂單流程 1. 刪除購物車 的該商品 2. 減庫存 3. insert order 主表 副表 ## redis 延遲隊列處理無效訂單 用戶點擊 確定訂單時 未支付 存 redis 20分鐘有效期 然后腳本每秒 和當前時間比較 小于當前時間的則 把該訂單狀態改為 已取消 恢復該訂單對應sku的庫存 存redis 訂單id time()+20min ![](https://img.kancloud.cn/11/60/1160f71b074baff581fb47bbedd2519b_930x491.png) ## 定時任務 ![](https://img.kancloud.cn/93/0b/930bd8479b6e77efecc6a253586ba301_945x700.png) ![](https://img.kancloud.cn/51/42/514256597f3978a22c8c82ecef2511cc_915x540.png) ![](https://img.kancloud.cn/93/fd/93fd21cdafba5d5d997f599f3b4dab79_1095x782.png) 暫時有bug 生成 所以要手動擋 ![](https://img.kancloud.cn/64/df/64dfc9dc4d62f6742094a9429e37d836_495x798.png) 最后在當前tp6 目錄的 命令行 運行 php think order 即可開啟進程 如果定時任務 進程掛了這么解決? supervise維持進程任務自動重啟 ## 支付抽離 單獨服務 子服務 微服務 ## 寫出用戶所有流程 支付流程 從購物車點擊進入結算 下單頁 先減庫存 點擊立即付款 跳轉支付界面 然后看支付回調 成功 失敗 進行數據庫處理 庫存等等… ## Start 前置中間件 檢測 是否登錄 || 創建一個base來繼承 在其中判斷 pathinfo 對比 判斷前端傳來的token 是否存在redis 登錄 注冊 用redis存儲60s 驗證碼 進行判斷 sms . 133333333 驗證碼 | sms 是標識 拼接手機號 作 k v是驗證碼 參3存活時間 登錄成功 redis 存儲 k => user\_token . 后臺生成唯一token v => 登錄的用戶信息 然后把token 給header頭 進首頁 驗證 注冊登錄 1. 登錄流程 驗證登錄 購物車 訂單 支付
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看