什麼是數據庫三大範式javascript
數據庫中設計中的常見問題php
一對一 (學生姓名, 學號)
一對多 (老師, 學生)
多對多 (學生, 課程)html
設計數據庫的小技巧java
數據庫名
作前綴表名
作前綴縮寫
基本語法sql
用戶登陸
舉例thinkphp
post
www.test.com/apiapi.test.com
數據庫
參數 | 必選 | 類型 | 說明 |
---|---|---|---|
time | true | int | 時間戳 (用於肯定接口的訪問時間) |
token | true | string | 肯定訪問者身份 (MD5(USER_MD5(time)_USER) ) |
username | true | string | 只接受手機號 |
password | true | string | 用戶密碼 |
{ "ret": 200, // 返回結果狀態。200:接口正常請求並返回/40*:服務端的數據有誤/500:服務器運行錯誤 "data": { "user_id": "27", // 用戶id "user_tag": "1" // 用戶身份 }, "msg": "" // 401:用戶名不存在!/402:手機號不存在!/403:密碼不正確! }
api.tp5.com/user/2
===> www.tp5.com/index.php/api/user/index/id/2
其餘選項菜單
==> 站點域名管理
網站域名:
www.tp5.com
網站域名:G:\phpStudy\WWW\tp5\public
第二域名:api.tp5.com
網站端口:80
json
127.0.0.1 www.tp5.com 127.0.0.1 api.tp5.com
package control: install package
SideBarEnhancementsapi
路徑:
G:\phpStudy\WWW\tp5\application\config.php
跨域// 是否開啓路由 'url_route_on' => true, // 域名部署 'url_domain_deploy' => true,
D:\phpStudy\WWW\tp5\application\route.php
<?php use think\Route; Route::domain('api', 'api'); Route::get('user', 'user/index');新建
api/controller/User.php
<?php namespace app\api\controller; class User { public function index() { echo 'user/index'; echo '<br>'; $id = input('id'); echo $id; echo '<br>'; $name = input('name'); print_r($name); } }訪問下面地址均可以打開:
http://api.tp5.com/user/index?id=1&name=lisi
http://api.tp5.com/user?id=1&name=lisi
http://api.tp5.com/user/id/1/name/lisi
http://www.tp5.com/api/user/index?id=1&name=lisi
http://www.tp5.com/api/user/index/id/1/name/lisi
輸出:user/index 1 lisi下面這些訪問拿不到參數
http://api.tp5.com/user/index/id/1/name/lisi
輸出:user/index
D:\phpStudy\WWW\tp5\application\route.php
<?php use think\Route; Route::domain('api', 'api'); Route::get('user/:id/:name', 'user/index');
新建 api/controller/User.php
<?php namespace app\api\controller; class User { public function index() { echo 'user/index'; echo '<br>'; $id = input('id'); echo $id; echo '<br>'; $name = input('name'); print_r($name); } }下面這些訪問拿不到參數
http://api.tp5.com/user/1/lisi
http://api.tp5.com/user?id=1&name=lisi
http://www.tp5.com/api/user/index?id=1&name=lisi
http://www.tp5.com/api/user?id=1&name=lisi
http://www.tp5.com/api/user/index/id/1/name/lisi
輸出:user/index 1 lisi*下面這種會報錯 *
http://api.tp5.com/user/index?id=1&name=lisi
非法請求:api/user/index
常見的安全問題以及解決方案
解決方案: 獲取 timestamp (時間戳), 設置接口失效時間
解決方案: 對參數加密, 生成 token , 判斷 token 是否正確
解決方案: 使用 https , 用證書對數據進行加密, 即便數據被截取, 對黑客也沒有意義
黑客能夠獲取數據, 可是沒法獲取數據的加密方法
咱們api項目的安全設計
時間戳, 用於判斷請求是否超時, 設置爲30秒
其餘參數加密而來, 保證數據不被篡改
接收加密過的用戶密碼, 用戶密碼永不返回
最好使用 https, 全部信息都會被加密
配置路由
G:\phpStudy\WWW\tp5\application\config.php
// 是否開啓路由 'url_route_on' => true, // 域名部署 'url_domain_deploy' => true,
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) { //intval() string 11返回11 11hello返回11 hello返回0 array 空array返回0 非空array返回1 //intval($arr['time']) <= 1 等於1就是非空array(不是咱們想要的) //小於1即等於0就是string或者空array或者是空(也不是咱們想要的) //我想要想要的是一串數字,因此 intval($arr['time']) <= 1就報錯 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; }
接口文檔
新建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;
驗證碼原理
- 點擊獲取手機碼
- 發送手機號到後臺
- 後臺生成手機碼
- 用session保存手機碼及手機號
- 用短信發送平臺的接口發送出去
- 獲取用戶輸入的手機碼及手機號
- 取出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(賽迪雲通訊)
- 開啓
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; }
- 下載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次, 請在一分鐘內驗證!'); } }
接口文檔
配置路由
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); }
接口文檔
配置路由
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); } }
接口文檔
配置路由
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; } }
接口文檔
配置路由
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, '密碼修改失敗!'); } }
接口文檔
配置路由
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, '密碼修改失敗!'); } }
接口文檔
配置路由
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, '郵箱綁定失敗!'); } }
兩個接口合成一個
G:\phpStudy\WWW\tp5\application\route.php
// 用戶綁定郵箱/手機 Route::post('user/bind_username','user/bind_username');
G:\phpStudy\WWW\tp5\application\api\controller\Common.php
'bind_username' => array( 'user_id' => 'require|number', 'user_name' => 'require', 'code' => 'require|number|length:6', ),
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 . '綁定失敗!'); } }
接口文檔
配置路由
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,'暱稱修改爲功!'); } }
接口文檔
新建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',
配置路由
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); } } }
接口文檔
配置路由
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); } } }
接口文檔
配置路由
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, '修改文章失敗!'); } } }
接口文檔
配置路由
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,'刪除文章失敗!'); } } }