"thinkphp5開發restful-api接口" 教程視頻 配套文檔

視頻配套文檔, 爲知筆記連接失效, 轉至掘金 :)

視頻教程地址:

thinkphp5開發restful-api接口javascript

正文


課程簡介

主要內容php

  1. 基於thinkphp5框架, 爲移動端APP開發數據接口
  2. php程序員最多見的工做

爲app寫後臺 爲app寫接口html

什麼是thinkphp5?java

  1. thinkphp5 是php框架thinkphp的最新的一個版本
  2. thinkphp官網
  3. thinkphp5手冊
  4. thinkphp的優勢

簡單易用 功能齊全 利於擴展 方便學習 開發速度快 教程豐富python

什麼是restful api?mysql

  • 一套api的設計規範

RESTful API 設計指南git

爲何是這種搭配程序員

  • 兼顧api和後臺

php: thinkphp5 + thinkcmf python: django + xadmingithub

本課程用到的工具sql

  1. php開發環境:phpstudy ==> windows + apache + mysql + php
  2. 編輯器:sublime
  3. 接口測試工具:postman
  4. 數據庫工具:navicat for mysql

本課程的風格

  1. 通俗易懂
  2. 配套文檔

本課程的學習基礎

  1. 有php基礎
  2. 熟悉mysql數據庫

本課程的收穫

  1. 學會了一門新的框架
  2. 學會如何爲APP提供接口

第1節 經常使用工具介紹

sublime(最性感的編輯器)

  • 最性感的編輯器

啓動速度快(C++) 插件衆多(python)

下載sublime

安裝版和綠色便攜版的區別

  1. 安裝板支持右鍵菜單, 可是不方便遷移
  2. 綠色便攜版方便遷移, 可是不支持右鍵菜單
  3. 推薦綠色便攜版, 右鍵菜單解決方案(sublime_addright.inf)
[Version]
Signature="$Windows NT$"

[DefaultInstall]
AddReg=SublimeText3

[SublimeText3]
hkcr,"*\\shell\\SublimeText3",,,"用 SublimeText3 打開"
hkcr,"*\\shell\\SublimeText3\\command",,,"""%1%\sublime_text.exe"" ""%%1"" %%*"
hkcr,"Directory\shell\SublimeText3",,,"用 SublimeText3 打開"
hkcr,"*\\shell\\SublimeText3","Icon",0x20000,"%1%\sublime_text.exe, 0"
hkcr,"Directory\shell\SublimeText3\command",,,"""%1%\sublime_text.exe"" ""%%1"""
複製代碼

激活sublime

  1. 不激活, 也沒事
  2. 激活碼, 簡單方便
  3. 激活碼
—– BEGIN LICENSE —–
Michael Barnes
Single User License
EA7E-821385
8A353C41 872A0D5C DF9B2950 AFF6F667
C458EA6D 8EA3C286 98D1D650 131A97AB
AA919AEC EF20E143 B361B1E7 4C8B7F04
B085E65E 2F5F5360 8489D422 FB8FC1AA
93F6323C FD7F7544 3F39C318 D95E6480
FCCC7561 8A4A1741 68FA4223 ADCEDE07
200C25BE DBBC4855 C4CFB774 C5EC138C
0FEC1CEF D9DCECEC D3A5DAD1 01316C36
—— END LICENSE ——
複製代碼
  1. 更多激活碼

sublime經常使用配置

{
    "font_face": "YaHei Consolas Hybrid", // 字體名稱
    "font_size": 13, // 字體大小
    "save_on_focus_lost": true, // 自動保存
    "word_wrap": true, // 開啓自動換行
}
複製代碼

sublime安裝插件

  1. 插件官網
  2. 安裝package control(ctrl + ~)
import urllib.request,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' + '1e3d39e33b79698005270310898eea76'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
複製代碼
  1. 搜索插件(ctrl + shift + p, package install)
  2. 安裝

postman(接口測試)

  1. postman的前世此生
  2. 官方文檔 (全英文, 圖文並茂)
  3. 測試接口

心知天氣接口: api.seniverse.com/v3/weather/…

  1. 經常使用設置

選擇 http 方法 自動生成代碼 接口鑑權 設置接受數據的方式 設置字體大小 保存接口以備後用 post 參數的兩種方式

navicat(數據庫管理)

  1. 下載與安裝
  2. 新建mysql鏈接
  3. 新建數據庫
  4. 新建數據表(圖形化界面/自動完成)
  5. 查看錶結構
  6. 原生sql查詢
  7. 導入/導出數據庫

phpstudy(php開發環境)

  1. 爲何選擇phpstudy

一次性安裝,無須配置便可使用 完美支持win10, 支持自定義php版本

  1. 啓動/中止/重啓

運行環境(選擇 非系統模式 就能夠了) 支持右鍵分開啓停 切換版本(切記: NTS版本的PHP,APACHE不支持REWRITE! )

  1. 快速跳轉配置文件

php-ini php配置文件(自動識別版本 http-conf apache配置文 mysql-ini mysql配置文 vhosts-conf apache虛擬主機配置文

  1. 快速跳轉軟件位置

hosts 網站根目錄

  1. 查看phpinfo

phpinfo路徑: G:\phpStudy\WWW\phpinfo.php

  1. php擴展及設置

php擴展 (等於直接操做 php.ini ) 參數開關設置 (等於直接操做 php.ini ) 參數值設置 (等於直接操做 php.ini )

  1. 操做mysql

快速打開命令行 快速新建數據庫 設置mysql (等於直接操做 mysql.ini ) MYSQL工具 =====> 參數值設置

  1. 爲apache增長模塊 (等於直接操做 httpd.conf )

第2節 以豆瓣網爲例, 講解restful api設計規範

什麼是restful api

  • 目前比較成熟的一套互聯網應用程序的API設計理論

豆瓣電影api

  1. 應該儘可能將API部署在專用域名之下

http://api.douban.com/v2/user/1000001?apikey=XXX

  1. 應該將API的版本號放入URL

http://api.douban.com/v2/user/1000001?apikey=XXX

  1. 在RESTful架構中,每一個網址表明一種資源(resource),因此網址中不能有動詞,只能有名詞,並且所用的名詞每每與數據庫的表格名對應。通常來講,數據庫中的表都是同種記錄的"集合"(collection),因此API中的名詞也應該使用複數。

api.douban.com/v2/book/:id (獲取圖書信息) api.douban.com/v2/movie/subject/:id (電影條目信息) api.douban.com/v2/music/:id (獲取音樂信息) api.douban.com/v2/event/:id (獲取同城活動)

  1. 對於資源的具體操做類型,由HTTP動詞表示。經常使用的HTTP動詞有下面四個(對應增/刪/改/查)。

GET(select):從服務器取出資源(一項或多項)。 eg. 獲取圖書信息 GET api.douban.com/v2/book/:id POST(create):在服務器新建一個資源。 eg. 用戶收藏某本圖書 POST api.douban.com/v2/book/:id… PUT(update):在服務器更新資源(客戶端提供改變後的完整資源)。 eg. 用戶修改對某本圖書的收藏 PUT api.douban.com/v2/book/:id… DELETE(delete):從服務器刪除資源。 eg. 用戶刪除某篇筆記 DELETE api.douban.com/v2/book/ann…

  1. 若是記錄數量不少,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果

?limit=10:指定返回記錄的數量 eg. 獲取圖書信息 GET api.douban.com/v2/book/:id?limit=10

  1. 服務器向用戶返回的狀態碼和提示信息

每一個狀態碼錶明不一樣意思, 就像代號同樣 2系 表明正常返回 4系 表明數據異常 5系 表明服務器異常

錯誤碼 錯誤信息 含義 狀態碼
6000 book_not_found 圖書不存在 404
6002 unauthorized_error 沒有修改權限 403
6004 review_content_short(should more than 150) 書評內容太短(需多於150字) 400
6006 review_not_found 書評不存在 404
6007 not_book_request 不是豆瓣讀書相關請求 403
6008 people_not_found 用戶不存在 404
6009 function_error 服務器調用異常 400
6010 comment_too_long(should less than 350) 短評字數過長(需少於350字) 400
6011 collection_exist(try PUT if you want to update) 該圖書已被收藏(如需更新請用PUT方法而不是POST) 409
6012 invalid_page_number(should be digit less than 1000000) 非法頁碼(頁碼須要是小於1000000的數字) 400
6013 chapter_too_long(should less than 100) 章節名過長(需小於100字) 400

接口安全

  1. API的身份認證應該使用OAuth 2.0框架。
  2. 技術團隊本身約定的規則

增長兩個參數 time, token time爲時間戳, 用於判斷接口請求是否超時 token爲時間戳加密後的字符串, 加密規則只有大家技術團隊本身知道


第3節 thinkphp5簡易教程

什麼是thinkphp

  1. 國人開發的php框架
  2. 源碼中文註釋, 方便理解
  3. 中文文檔詳盡
  4. 使用者多, 教程豐富

官網

安裝

  1. 官網下載, 複製粘貼
  2. 檢查環境
  3. 訪問public文件夾

配置虛擬主機

  1. 配置vhosts-conf
  2. 修改hosts

URL路徑設計

格式化php代碼

  1. 安裝phpfmt插件

ctrl+shift+p 搜索phpfmt enter

  1. 配置插件
{
    "format_on_save": true,
    "php_bin": "G:/phpStudy/php/php-7.0.12-nts/php.exe",
}
複製代碼
  1. psr1和psr2區別

花括號點位置不一樣

API友好

<?php
namespace app\index\controller;
class Index {
    public function index() {
        $data = array(
            'name' => 'red_panda',
            'address' => 'China',
        );
        $code = 200;
        $msg = 'ok';
        return ['data' => $data, 'code' => $code, 'message' => $msg];
    }
}
複製代碼
'default_return_type'=>'json'
複製代碼

獲取請求參數

<?php
namespace app\index\controller;
use \think\Request;
class Index {
    public function index() {
        $request = Request::instance();
        echo '請求方法:' . $request->method() . '<br/>';
        echo '訪問地址:' . $request->ip() . '<br/>';
        echo '請求參數:';
        dump($request->param());
        echo '請求參數:僅包含name,sex';
        dump($request->only(['name', 'sex']));
        echo '請求參數:排除name,sex';
        dump($request->except(['name', 'sex']));
    }
}
複製代碼

判斷請求類型

// 是否爲 GET 請求
if (Request::instance()->isGet()) echo "當前爲 GET 請求";
// 是否爲 POST 請求
if (Request::instance()->isPost()) echo "當前爲 POST 請求";
// 是否爲 PUT 請求
if (Request::instance()->isPut()) echo "當前爲 PUT 請求";
// 是否爲 DELETE 請求
if (Request::instance()->isDelete()) echo "當前爲 DELETE 請求";
// 是否爲 Patch 請求
if (Request::instance()->isPatch()) echo "當前爲 PATCH 請求";
複製代碼

驗證參數數據

<?php
namespace app\index\controller;
use \think\Validate;
class Index {
    public function index() {
        $rule = [
            'name' => 'require|max:25',
            'age' => 'number|between:1,120',
            'email' => 'email',
        ];
        $msg = [
            'name.require' => '名稱必須',
            'name.max' => '名稱最多不能超過25個字符',
            'age.number' => '年齡必須是數字',
            'age.between' => '年齡只能在1-120之間',
            'email' => '郵箱格式錯誤',
        ];
        $data = input('post.');
        $validate = new Validate($rule, $msg);
        $result = $validate->check($data);
        if (!$validate->check($data)) {
            dump($validate->getError());
        }
    }
}
複製代碼

鏈接數據庫

/* 數據庫設置 */
'database' => [
    // 數據庫類型
    'type'        => 'mysql',
    // 服務器地址
    'hostname'    => '127.0.0.1',
    // 數據庫名
    'database'    => 'thinkphp',
    // 數據庫用戶名
    'username'    => 'root',
    // 數據庫密碼
    'password'    => '',
    // 數據庫鏈接端口
    'hostport'    => '',
    // 數據庫鏈接參數
    'params'      => [],
    // 數據庫編碼默認採用utf8
    'charset'     => 'utf8',
    // 數據庫表前綴
    'prefix'      => '',
    // 數據庫調試模式
    'debug'       => false,
],
複製代碼

原生sql語句查詢

<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index() {
        $res = Db::query('select version()');
        return $res;
    }
}
複製代碼

第4節 爲api項目搭建數據庫

什麼是數據庫三大範式

  1. 每一列都是不可分割的原子數據項
  2. 實體的屬性徹底依賴於主關鍵字
  3. 任何非主屬性不依賴於其它非主屬性(在2NF基礎上消除傳遞依賴)

數據庫中設計中的常見問題

  1. 字段混在了一塊兒

  1. 數據表混在了一塊兒

  1. 不會處理表關係

一對一 (學生姓名, 學號) 一對多 (老師, 學生) 多對多 (學生, 課程)

設計數據庫的小技巧

  1. 一個對象, 一張表
  2. 一張表, 一個主鍵
  3. 表名中有數據庫名作前綴
  4. 字段名中有表名作前綴
  5. 前綴後加縮寫
  6. 數據表關係處理

範式越高越好?


第5節 使用markdown書寫接口文檔

基本語法

  1. 六級標題
  2. 目錄索引
  3. 加粗
  4. 斜體
  5. 刪除線
  6. 引用
  7. 代碼段
  8. 表格
  9. 行內代碼
  10. 無序列表
  11. 有序列表
  12. 圖片
  13. 超連接

用戶登陸舉例

---
 # 第6節(判斷數據庫中是否有此用戶)
 > `post` ~~www.test.com/api~~ `api.test.com`
 |參數|必選|類型|說明|
 |:-|:-:|:-:|:-|
 |*time*|*true*|*int*|*時間戳* (用於肯定接口的訪問時間)|
 |*token*|*true*|*string*|*肯定訪問者身份* (`MD5(USER_MD5(time)_USER)`)|
 |username |true |string|只接受`手機號`|
 |password |true |string |用戶密碼|
 ``` javascript
 {
 "ret": 200, // 返回結果狀態。200:接口正常請求並返回/40*:服務端的數據有誤/500:服務器運行錯誤
 "data": {
 "user_id": "27", // 用戶id
 "user_tag": "1" // 用戶身份
 },
 "msg": "" // 401:用戶名不存在!/402:手機號不存在!/403:密碼不正確!
 }
 ```
複製代碼

第7節 爲項目配置URL

需求分析

  • api.tp5.com/user/2 ===> www.tp5.com/index.php/api/user/index/id/2

配置主域名和二級域名

  1. 打開phpstudy
  2. 其餘選項菜單 ==> 站點域名管理

網站域名:www.tp5.com 網站域名:G:\phpStudy\WWW\tp5\public 第二域名:api.tp5.com 網站端口: 80

  1. 配置hosts(域名重定向)
127.0.0.1 www.tp5.com
127.0.0.1 api.tp5.com
複製代碼

使用tp5路由進行URL解析

  1. 爲sublime安裝新插件(方便操做側邊欄)

package control: install package SideBarEnhancements

  1. 新建user.php文件

路徑:G:\phpStudy\WWW\tp5\application\api\controller\User.php

<?php
namespace app\api\controller;

class User{
    public function index($id){
        echo 'controller: user function: index';
        echo '<br/>';
        echo $id;
    }
}
複製代碼
  1. 修改config.php(開啓路由功能)

路徑:G:\phpStudy\WWW\tp5\application\config.php

// 是否開啓路由
'url_route_on' => true,
複製代碼
  1. 配置路由規則

路徑:G:\phpStudy\WWW\tp5\application\route.php

<?php
use think\Route;

// api.tp5.com ===> www.tp5.com/index.php/api
Route::domain('api','api');
// api.tp5.com/user/2 ===> www.tp5.com/index.php/api/user/index/id/2
Route::rule('user/:id','user/index');
複製代碼

第8節 接口安全

常見的安全問題以及解決方案

  1. 接口被大規模調用消耗系統資源,影響系統的正常訪問,甚至系統癱瘓

解決方案: 獲取 timestamp (時間戳), 設置接口失效時間

  1. 接口數據被黑客篡改(僞造請求)

解決方案: 對參數加密, 生成 token , 判斷 token 是否正確

  1. 數據被黑客截取

解決方案: 使用 https , 用證書對數據進行加密, 即便數據被截取, 對黑客也沒有意義

黑客能夠獲取數據, 可是沒法獲取數據的加密方法

咱們api項目的安全設計

  1. time

時間戳, 用於判斷請求是否超時, 設置爲30秒

  1. token

其餘參數加密而來, 保證數據不被篡改

  1. 敏感信息加密傳輸

接收加密過的用戶密碼, 用戶密碼永不返回 最好使用 https, 全部信息都會被加密

第9節 接口開發前的準備工做(參數過濾)

配置路由

  1. 開啓路由功能

G:\phpStudy\WWW\tp5\application\config.php

// 是否開啓路由
'url_route_on' => true,
// 域名部署
'url_domain_deploy' => true,
複製代碼
  1. 配置route.php

G:\phpStudy\WWW\tp5\application\route.php

<?php
use think\Route;

// api.tp5.com ===> www.tp5.com/index.php/api
Route::domain('api','api');
// post api.tp5.com/user ---> user.php login()
Route::post('user','user/login');
複製代碼

使用common.php統一處理參數過濾 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

<?php
namespace app\api\controller;
use think\Controller;
use think\Request;
use think\Validate;
class Common extends Controller {
    protected $request; // 用來處理參數
    protected $validater; // 用來驗證數據/參數
    protected $params; // 過濾後符合要求的參數
    protected $rules = array(
            'User'=>array(......);
    protected function _initialize() {
        parent::_initialize();
        $this->request = Request::instance();
        $this->check_time($this->request->only(['time']));
        $this->check_token($this->request->param());
        $this->params = $this->check_params($this->request->except(['time','token']));
    }
複製代碼

自定義返回信息函數 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

/** * api 數據返回 * @param [int] $code [結果碼 200:正常/4**數據問題/5**服務器問題] * @param [string] $msg [接口要返回的提示信息] * @param [array] $data [接口要返回的數據] * @return [string] [最終的json數據] */
public function return_msg($code, $msg = '', $data = []) {
 
    /*********** 組合數據 ***********/
    $return_data['code'] = $code;
    $return_data['msg']  = $msg;
    $return_data['data'] = $data;
 
    /*********** 返回信息並終止腳本 ***********/
    echo json_encode($return_data);die;
}
複製代碼

驗證time G:\phpStudy\WWW\tp5\application\api\controller\Common.php

/** * 驗證請求是否超時 * @param [array] $arr [包含時間戳的參數數組] * @return [json] [檢測結果] */
public function check_time($arr) {
    if (!isset($arr['time']) || intval($arr['time']) <= 1) {
        $this->return_msg(400, '時間戳不正確!');
    }
    if (time() - intval($arr['time']) > 60) {
        $this->return_msg(400, '請求超時!');
    }
}
複製代碼

驗證token G:\phpStudy\WWW\tp5\application\api\controller\Common.php

/** * 驗證token(防止篡改數據) * @param [array] $arr [所有請求參數] * @return [json] [token驗證結果] */
public function check_token($arr) {
 
    /*********** api傳過來的token ***********/
    if (!isset($arr['token']) || empty($arr['token'])) {
        $this->return_msg(400, 'token不能爲空!');
    }
    $app_token = $arr['token']; // api傳過來的token
 
    /*********** 服務器端生成token ***********/
    unset($arr['token']);
    $service_token = '';
    foreach ($arr as $key => $value) {
        $service_token .= md5($value);
    }
    $service_token = md5('api_' . $service_token . '_api'); // 服務器端即時生成的token
 
    /*********** 對比token,返回結果 ***********/
    if ($app_token !== $service_token) {
        $this->return_msg(400, 'token值不正確!');
    }
}
複製代碼

爲每一個接口配置驗證規則 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'login' => array(
            'user_name' => ['require', 'chsDash', 'max' => 20],
            'user_pwd'  => 'require|length:32',
        ),
    ),
);
複製代碼

驗證參數 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

/** * 驗證參數 參數過濾 * @param [array] $arr [除time和token外的全部參數] * @return [return] [合格的參數數組] */
public function check_params($arr) {
 
    /*********** 獲取參數的驗證規則 ***********/
    $rule = $this->rules[$this->request->controller()][$this->request->action()];
 
    /*********** 驗證參數並返回錯誤 ***********/
    $this->validater = new Validate($rule);
    if (!$this->validater->check($arr)) {
        $this->return_msg(400, $this->validater->getError());
    }
 
    /*********** 若是正常,經過驗證 ***********/
    return $arr;
}
複製代碼

第9節 獲取驗證碼

接口文檔 新建api_user表

DROP TABLE IF EXISTS `api_user`;
CREATE TABLE `api_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_phone` char(11) NOT NULL,
  `user_nickname` varchar(255) NOT NULL COMMENT '暱稱',
  `user_email` varchar(255) NOT NULL,
  `user_rtime` int(11) NOT NULL COMMENT 'register time',
  `user_pwd` char(32) NOT NULL,
  `user_icon` varchar(255) NOT NULL COMMENT '用戶頭像',
  PRIMARY KEY (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
複製代碼

驗證碼原理

  1. 生成及發送
  • 點擊獲取手機碼
  • 發送手機號到後臺
  • 後臺生成手機碼
  • 用session保存手機碼及手機號
  • 用短信發送平臺的接口發送出去
  1. 驗證
  • 獲取用戶輸入的手機碼及手機號
  • 取出session保存的內容
  • 對比驗證
  • 返回信息, 結束

配置路由

注意: get方式沒有參數名, 因此要注意參數的順序, 對號入座.

G:\phpStudy\WWW\tp5\application\route.php

// 獲取驗證碼
Route::get('code/:time/:token/:username/:is_exist','code/get_code');
複製代碼

參數過濾

在common.php裏簡單過濾, 具體驗證放在code.php裏

G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Code' => array(
    'get_code' => array(
        'username' => 'require',
        'is_exist' => 'require|number|length:1',
    ),
),
複製代碼

檢測用戶名 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

namespace app\api\controller;
use phpmailer\phpmailer;
use submail\messagexsend;
 
class Code extends Common {
    public function get_code() {
        $username      = $this->params['username'];
        $exist         = $this->params['is_exist'];
        $username_type = $this->check_username($username); // 檢查用戶名, 決定用下面哪那個函數
        switch ($username_type) {
        case 'phone':
            $this->get_code_by_username($username, 'phone', $exist); // 經過手機獲取驗證碼
            break;
        case 'email':
            $this->get_code_by_username($username, 'email', $exist); // 經過郵箱獲取驗證碼
            break;
        }
    }
}
複製代碼

G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function check_username($username) {
    /*********** 判斷是否爲郵箱 ***********/
    $is_email = Validate::is($username, 'email') ? 1 : 0;
    /*********** 判斷是否爲手機 ***********/
    $is_phone = preg_match('/^1[34578]\d{9}$/', $username) ? 4 : 2;
    /*********** 最終結果 ***********/
    $flag = $is_email + $is_phone;
    switch ($flag) {
    /*********** not phone not email ***********/
    case 2:
        $this->return_msg(400, '郵箱或手機號不正確!');
        break;
    /*********** is email not phone ***********/
    case 3:
        return 'email';
        break;
    /*********** is phone not email ***********/
    case 4:
        return 'phone';
        break;
    }
}
複製代碼

經過用戶名(手機/郵箱)獲取驗證碼 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

public function get_code_by_username($username, $type, $exist) {
    if ($type == 'phone') {
        $type_name = '手機';
    } else {
        $type_name = '郵箱';
    }
    /*********** 檢測手機號/郵箱是否存在 ***********/
    $this->check_exist($username, $type, $exist);
    /*********** 檢查驗證碼請求頻率 30秒一次 ***********/
    if (session("?" . $username . '_last_send_time')) {
        if (time() - session($username . '_last_send_time') < 30) {
            $this->return_msg(400, $type_name . '驗證碼,每30秒只能發送一次!');
        }
    }
    /*********** 生成驗證碼 ***********/
    $code = $this->make_code(6);
    /*********** 使用session存儲驗證碼, 方便比對, md5加密 ***********/
    $md5_code = md5($username . '_' . md5($code));
    session($username . '_code', $md5_code);
    /*********** 使用session存儲驗證碼的發送時間 ***********/
    session($username . '_last_send_time', time());
    /*********** 發送驗證碼 ***********/
    if ($type == 'phone') {
        $this->send_code_to_phone($username, $code);
    } else {
        $this->send_code_to_email($username, $code);
    }
}
複製代碼

判斷用戶名(手機/郵箱)是否應該存在 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function check_exist($value, $type, $exist) {
    $type_num  = $type == "phone" ? 2 : 4;
    $flag      = $type_num + $exist;
    $phone_res = db('user')->where('user_phone', $value)->find();
    $email_res = db('user')->where('user_email', $value)->find();
    switch ($flag) {
    /*********** 2+0 phone need no exist ***********/
    case 2:
        if ($phone_res) {
            $this->return_msg(400, '此手機號已被佔用!');
        }
        break;
    /*********** 2+1 phone need exist ***********/
    case 3:
        if (!$phone_res) {
            $this->return_msg(400, '此手機號不存在!');
        }
        break;
    /*********** 4+0 email need no exist ***********/
    case 4:
        if ($email_res) {
            $this->return_msg(400, '此郵箱已被佔用!');
        }
        break;
    /*********** 4+1 email need exist ***********/
    case 5:
        if (!$email_res) {
            $this->return_msg(400, '此郵箱不存在!');
        }
        break;
    }
}
複製代碼

生成驗證碼 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

public function make_code($num) {
    $max = pow(10, $num) - 1;
    $min = pow(10, $num - 1);
    return rand($min, $max);
}
複製代碼

經過郵箱發送驗證碼

去郵箱開啓smtp php須要開啓php_openssl 如今phpmailer並把須要的文件添加進thinkphp5

  • G:\phpStudy\WWW\tp5\extend\phpmailer\phpmailer.php
namespace phpmailer;
use phpmailer\smtp;
class PHPMailer ...... class phpmailerException extends \Exception...... // 須要加\ 複製代碼
  • G:\phpStudy\WWW\tp5\extend\phpmailer\smtp.php
namespace phpmailer;
class SMTP ...... 複製代碼

G:\phpStudy\WWW\tp5\application\api\controller\Code.php

public function send_code_to_email($email, $code) {
    $toemail = $email;
    $mail    = new PHPMailer();
    $mail->isSMTP();
    $mail->CharSet    = 'utf8'; // 設置字符集
    $mail->Host       = 'smtp.126.com'; // smtp服務器
    $mail->SMTPAuth   = true;
    $mail->Username   = "xujunhao_api@126.com";
    $mail->Password   = "xujunhao890518"; // 本身設置的smtp密碼, 與登陸密碼無關
    $mail->SMTPSecure = 'ssl';
    $mail->Port       = 994;
    $mail->setFrom('xujunhao_api@126.com', '接口測試');
    $mail->addAddress($toemail, 'test');
    $mail->addReplyTo('xujunhao_api@126.com', 'Reply');
    $mail->Subject = "您有新的驗證碼!"; // 郵件標題
    $mail->Body    = "這是一個測試郵件,您的驗證碼是$code,驗證碼的有效期爲1分鐘,本郵件請勿回覆!"; // 郵件內容
    if (!$mail->send()) {
        $this->return_msg(400, $mail->ErrorInfo);
    } else {
        $this->return_msg(200, '驗證碼已經發送成功,請注意查收!');
    }
}
複製代碼

經過手機發送驗證碼 使用submail(賽迪雲通訊)

  1. 經過調用接口發送短信
  • 開啓php_curl
  • 安裝本地證書下載證書
  • G:\phpStudy\php\php-5.5.38\php.ini
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "G:\phpStudy\php\php-5.5.38\cacert.pem"
複製代碼
  • G:\phpStudy\WWW\tp5\application\api\controller\Code.php
public function send_code_to_phone($phone, $code) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://api.mysubmail.com/message/xsend');
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    $data = [
        'appid'   => '15180',
        'to'      => $phone,
        'project' => '9CTTG2',
        'vars'    => '{"code":' . $code . ',"time":"60"}',
        'signature'=>'76a9e82484c83345b7850395ceb818fb',
    ];
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    $res = curl_exec($curl);
    curl_close($curl);
    $res = json_decode($res);
    if ($res->status != 'success') {
        $this->return_msg(400,$res->msg);
    }else{
        $this->return_msg(200,'手機驗證碼已發送, 天天發送5次, 請在一分鐘內驗證!');
    }
    dump($res->staus);die;
}
複製代碼
  1. 使用sdk發送驗證碼
  • 下載sdk, 把須要的文件加入thinkphp5
  • G:\phpStudy\WWW\tp5\extend\submail\message.php
namespace submail;
class message {......
複製代碼
  • G:\phpStudy\WWW\tp5\extend\submail\messagexsend.php
namespace submail;
use submail\message;
class MESSAGEXsend {

    protected $appid = '';

    protected $appkey = '';

    protected $sign_type = '';

    protected $To = array();

    protected $Addressbook = array();

    protected $Project = '';

    protected $Vars = array();

    function __construct() {
        $this->appid  = "15180";
        $this->appkey = "76a9e82484c83345b7850395ceb818fb";
        $this->sign_type = 'normal';
    }
複製代碼
  • G:\phpStudy\WWW\tp5\application\api\controller\Code.php
public function send_code_to_phone($phone, $code) {
    $submail = new MESSAGEXsend();
    $submail->SetTo($phone);
    $submail->SetProject('9CTTG2');
    $submail->AddVar('code', $code);
    $submail->AddVar('time', 60);
    $xsend = $submail->xsend();
    if ($xsend['status'] !== 'success') {
        $this->return_msg(400, $xsend['msg']);
    } else {
        $this->return_msg(200, '手機驗證碼已發送, 天天發送5次, 請在一分鐘內驗證!');
    }
}
複製代碼

第10節 用戶註冊

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶註冊
Route::post('user/register','user/register');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'register' => array(
            'user_name' => 'require',
            'user_pwd'  => 'require|length:32',
            'code'      => 'require|number|length:6',
        ),
    ),
);
複製代碼

關閉數據庫字段檢查 G:\phpStudy\WWW\tp5\application\database.php

// 是否嚴格檢查字段是否存在
'fields_strict'   => false,
複製代碼

書寫register函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function register() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢查驗證碼 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 檢測用戶名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 0);
        $data['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 0);
        $data['user_email'] = $data['user_name'];
        break;
    }
    /*********** 將用戶信息寫入數據庫 ***********/
    unset($data['user_name']);
    $data['user_rtime'] = time(); // register time
    $res                = db('user')->insert($data);
    if (!$res) {
        $this->retrun_msg(400, '用戶註冊失敗!');
    } else {
        $this->return_msg(200, '用戶註冊成功!');
    }
}
複製代碼

檢查驗證碼 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function check_code($user_name, $code) {
    /*********** 檢測是否超時 ***********/
    $last_time = session($user_name . '_last_send_time');
    if (time() - $last_time > 60) {
        $this->return_msg(400, '驗證超時,請在一分鐘內驗證!');
    }
    /*********** 檢測驗證碼是否正確 ***********/
    $md5_code = md5($user_name . '_' . md5($code));
    if (session($user_name . "_code") !== $md5_code) {
        $this->return_msg(400, '驗證碼不正確!');
    }
    /*********** 無論正確與否,每一個驗證碼只驗證一次 ***********/
    session($user_name . '_code', null);
}
複製代碼

第11節 用戶登陸

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶登陸
Route::post('user/login','user/login');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'login'    => array(
            'user_name' => 'require',
            'user_pwd'  => 'require|length:32',
        ),
    ),
);
複製代碼

書寫login函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function login() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢測用戶名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $db_res = db('user')
            ->field('user_id,user_name,user_phone,user_email,user_rtime,user_pwd')
            ->where('user_phone', $data['user_name'])
            ->find();
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $db_res = db('user')
            ->field('user_id,user_name,user_phone,user_email,user_rtime,user_pwd')
            ->where('user_email', $data['user_name'])
            ->find();
        break;
    }
    if ($db_res['user_pwd'] !== $data['user_pwd']) {
        $this->return_msg(400, '用戶名或者密碼不正確!');
    } else {
        unset($db_res['user_pwd']); // 密碼永不返回
        $this->return_msg(200, '登陸成功!', $db_res);
    }
}
複製代碼

第12節 用戶上傳頭像

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶上傳你頭像
Route::post('user/icon','user/upload_head_img');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'upload_head_img' => array(
            'user_id'   => 'require|number',
            'user_icon' => 'require|image|fileSize:2000000000|fileExt:jpg,png,bmp,jpeg',
        ),
    ),
);
複製代碼

修改參數過濾 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

$this->params = $this->check_params($this->request->param(true));
複製代碼

編寫upload_head_img函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function upload_head_img() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 上傳文件,得到路徑 ***********/
    $head_img_path = $this->upload_file($data['user_icon'], 'head_img');
    /*********** 存入數據庫 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_icon', $head_img_path);
    if ($res) {
        $this->return_msg(200, '頭像上傳成功!', $head_img_path);
    } else {
        $this->return_msg(400, '上傳頭像失敗!');
    }
}
複製代碼

編寫upload_file函數 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function upload_file($file, $type = '') {
    $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
    if ($info) {
        $path = '/uploads/' . $info->getSaveName();
        /*********** 裁剪圖片 ***********/
        if (!empty($type)) {
            $this->image_edit($path, $type);
        }
        return str_replace('\\', '/', $path);
    } else {
        $this->return_msg(400, $file->getError());
    }
}
複製代碼

編寫image_edit函數 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function image_edit($path, $type) {
    $image = Image::open(ROOT_PATH . 'public' . $path);
    switch ($type) {
    case 'head_img':
        $image->thumb(200, 200, Image::THUMB_CENTER)->save(ROOT_PATH . 'public' . $path);
        break;
    }
}
複製代碼

第13節 用戶修改密碼

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶修改密碼
Route::post('user/change_pwd','user/change_pwd');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'change_pwd'      => array(
            'user_name'    => 'require',
            'user_ini_pwd' => 'require|length:32',
            'user_pwd'     => 'require|length:32',
        ),
    ),
);
複製代碼

編寫change_pwd函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function change_pwd() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢查用戶名並取出數據庫中的密碼 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $where['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $where['user_email'] = $data['user_name'];
        break;
    }
    /*********** 判斷原始密碼是否正確 ***********/
    $db_ini_pwd = db('user')->where($where)->value('user_pwd');
    if ($db_ini_pwd !== $data['user_ini_pwd']) {
        $this->return_msg(400, '原密碼錯誤!');
    }
    /*********** 把新的密碼存入數據庫 ***********/
    $res = db('user')->where($where)->setField('user_pwd', $data['user_pwd']);
    if ($res !== false) {
        $this->return_msg(200, '密碼修改爲功!');
    } else {
        $this->return_msg(400, '密碼修改失敗!');
    }
}
複製代碼

第14節 找回密碼

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶找回密碼
Route::post('user/find_pwd','user/find_pwd');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'find_pwd'        => array(
            'user_name' => 'require',
            'user_pwd'  => 'require|length:32',
            'code'      => 'require|number|length:6',
        ),
    ),
);
複製代碼

書寫find_pwd函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function find_pwd() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢測驗證碼 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 檢測用戶名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $where['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $where['user_email'] = $data['user_name'];
        break;
    }
    /*********** 修改數據庫 ***********/
    $res = db('user')->where($where)->setField('user_pwd', $data['user_pwd']);
    if ($res !== false) {
        $this->return_msg(200, '密碼修改爲功!');
    } else {
        $this->return_msg(400, '密碼修改失敗!');
    }
}
複製代碼

第15節 用戶手機號/郵箱綁定

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶綁定手機號
Route::post('user/bind_phone','user/bind_phone');
// 用戶綁定郵箱
Route::post('user/bind_email','user/bind_email');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'bind_phone'        => array(
    'user_id' => 'require|number',
    'phone'  => ['require','regex'=>'/^1[34578]\d{9}$/'],
    'code'      => 'require|number|length:6',
),
 
'bind_email'        => array(
    'user_id' => 'require|number',
    'email'  => 'require|email',
    'code'      => 'require|number|length:6',
),
複製代碼

書寫bind_phone函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function bind_phone() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢查驗證碼 ***********/
    $this->check_code($data['phone'], $data['code']);
    /*********** 修改數據庫 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_phone', $data['phone']);
    if ($res !== false) {
        $this->return_msg(200, '手機號綁定成功!');
    } else {
        $this->return_msg(400, '手機號綁定失敗!');
    }
}
複製代碼

書寫bind_email函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function bind_email() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢查驗證碼 ***********/
    $this->check_code($data['email'], $data['code']);
    /*********** 修改數據庫 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_email', $data['email']);
    if ($res !== false) {
        $this->return_msg(200, '郵箱綁定成功!');
    } else {
        $this->return_msg(400, '郵箱綁定失敗!');
    }
}
複製代碼

兩個接口合成一個

  1. 配置路由

G:\phpStudy\WWW\tp5\application\route.php

// 用戶綁定郵箱/手機
Route::post('user/bind_username','user/bind_username');
複製代碼
  1. 驗證數據

G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'bind_username'        => array(
    'user_id' => 'require|number',
    'user_name'  => 'require',
    'code'      => 'require|number|length:6',
),
複製代碼
  1. 書寫bind_username函數

G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function bind_username() {
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢測驗證碼 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 判斷用戶名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $type_text                 = '手機號';
        $update_data['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $type_text                 = '郵箱';
        $update_data['user_email'] = $data['user_name'];
        break;
    }
    /*********** 修改數據庫 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->update($update_data);
    if ($res !== false) {
        $this->return_msg(200, $type_text . '綁定成功!');
    } else {
        $this->return_msg(400, $type_text . '綁定失敗!');
    }
}
複製代碼

第16節 用戶修改暱稱

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 用戶修改暱稱
Route::post('user/nickname','user/set_nickname');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'set_nickname'        => array(
    'user_id' => 'require|number',
    'user_nickname'  => 'require|chsDash',
),
複製代碼

編寫set_nickname函數 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function set_nickname(){
    /*********** 接收參數 ***********/
    $data = $this->params;
    /*********** 檢測暱稱 ***********/
    $res = db('user')->where('user_nickname',$data['user_nickname'])->find();
    if ($res) {
        $this->return_msg(400,'該暱稱已被佔用!');
    }
    /*********** 寫入數據庫 ***********/
    $res = db('user')->where('user_id',$data['user_id'])->setField('user_nickname',$data['user_nickname']);
    if (!$res) {
        $this->return_msg(400,'修改暱稱失敗!');
    }else{
        $this->return_msg(200,'暱稱修改爲功!');
    }
}
複製代碼

第17節 新增文章

接口文檔 新建api_article表

DROP TABLE IF EXISTS `api_article`;
CREATE TABLE `api_article` (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `article_title` varchar(255) NOT NULL,
  `article_uid` int(11) NOT NULL COMMENT 'user id',
  `article_content` text NOT NULL,
  `article_ctime` int(11) NOT NULL,
  PRIMARY KEY (`article_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
複製代碼

配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 新增文章
Route::post('article','article/add_article');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'add_article' => array(
        'article_uid' => 'require|number',
        'article_title' => 'require|chsDash',
    ),
),
複製代碼

編寫add_article函數 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function add_article() {
        /*********** 接收參數 ***********/
        $data                  = $this->params;
        $data['article_ctime'] = time();
        /*********** 寫入數據庫 ***********/
        $res = db('article')->insertGetId($data);
        if ($res) {
            $this->return_msg(200, '新增文章成功!',$res);
        } else {
            $this->return_msg(400, '新增文章失敗!');
        }
    }
}
複製代碼

參數安全html代碼實體化

防止跨域腳本攻擊

G:\phpStudy\WWW\tp5\application\config.php

// 默認全局過濾方法 用逗號分隔多個
'default_filter'         => 'htmlspecialchars',
複製代碼

第18節 查看文章列表

接口文檔

配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 查看文章列表
Route::get('articles/:time/:token/:user_id/[:num]/[:page]','article/article_list');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'article_list' => array(
        'user_id' => 'require|number',
        'num' => 'number',
        'page' => 'number',
    ),
),
複製代碼

編寫article_list函數 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function article_list() {
        /*********** 接收參數 ***********/
        $data = $this->params;
        if (!isset($data['num'])) {
            $data['num'] = 10;
        }
        if (!isset($data['page'])) {
            $data['page'] = 1;
        }
        /*********** 查詢數據庫 ***********/
        $where['article_uid'] = $data['user_id'];
        $where['article_isdel'] = 0;
        $count                = db('article')->where($where)->count();
        $page_num             = ceil($count / $data['num']);
        $field                = "article_id,article_ctime,article_title,user_nickname";
        $join                 = [['api_user u', 'u.user_id = a.article_uid']];
        $res                  = db('article')->alias('a')->field($field)->join($join)->where($where)->page($data['page'], $data['num'])->select();
        /*********** 判斷並輸出 ***********/
        if ($res === false) {
            $this->return_msg(400, '查詢失敗!');
        } elseif (empty($res)) {
            $this->return_msg(200, '暫無數據!');
        } else {
            $return_data['articles'] = $res;
            $return_data['page_num'] = $page_num;
            $this->return_msg(200, '查詢成功!', $return_data);
        }
    }
}
複製代碼

第19節 查看單個文章

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 獲取單個文章信息
Route::get('article/:time/:token/:article_id','article/article_detail');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'article_detail' => array(
        'article_id' => 'require|number',
    ),
),
複製代碼

編寫article_detail函數 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function article_detail() {
        /*********** 接收參數 ***********/
        $data = $this->params;
        /*********** 查詢數據庫 ***********/
        $field                  = 'article_id,article_title,article_ctime,article_content,user_nickname';
        $where['article_id']    = $data['article_id'];
        $join                   = [['api_user u', 'u.user_id = a.article_uid']];
        $res                    = db('article')->alias('a')->join($join)->field($field)->where($where)->find();
        $res['article_content'] = htmlspecialchars_decode($res['article_content']);
        /*********** 判斷結果並輸出 ***********/
        if (!$res) {
            $this->return_msg(400, '查詢失敗!');
        } else {
            $this->return_msg(200, '查詢成功!', $res);
        }
    }
}
複製代碼

第20節 修改文章

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 修改/更新文章
Route::put('article','article/update_article');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'update_article' => array(
        'article_id' => 'require|number',
        'article_title'=>'chsDash'
    ),
),
複製代碼

編寫update_article函數 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function update_article() {
        /*********** 接收參數 ***********/
        $data = $this->params;
        /*********** 存入數據庫 ***********/
        $res = db('article')->where('article_id', $data['article_id'])->update($data);
        if ($res !== false) {
            $this->return_msg(200, '修改文章成功!');
        } else {
            $this->return_msg(400, '修改文章失敗!');
        }
    }
}
複製代碼

第21節 刪除文章

接口文檔 配置路由 G:\phpStudy\WWW\tp5\application\route.php

// 刪除文章
Route::delete('article/:time/:token/:article_id','article/del_article');
複製代碼

驗證數據 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'del_article' => array(
        'article_id' => 'require|number',
    ),
),
複製代碼

爲邏輯刪除增長字段article_isdel

DROP TABLE IF EXISTS `api_article`;
CREATE TABLE `api_article` (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `article_title` varchar(255) NOT NULL,
  `article_uid` int(11) NOT NULL COMMENT 'user id',
  `article_content` text NOT NULL,
  `article_ctime` int(11) NOT NULL,
  `article_isdel` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否刪除 1:yes 0:no',
  PRIMARY KEY (`article_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
複製代碼

編寫del_article函數 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function del_article(){
        /*********** 接收參數 ***********/
        $data = $this->params;
        /*********** 刪除數據(邏輯刪除) ***********/
        $res = db('article')->where('article_id',$data['article_id'])->setField('article_isdel',1);
        /*********** 刪除數據(物理刪除) ***********/
        // $res = db('article')->delete($data['article_id']);
        if ($res) {
            $this->return_msg(200,'刪除文章成功');
        }else{
            $this->return_msg(400,'刪除文章失敗!');
        }
    }
}
複製代碼
相關文章
相關標籤/搜索