Restful API登錄和注冊實戰開發


本地開發環境


 

使用本地apache和mysql,配置www.api.com虛擬主機。

接口項目需求

 


  1. 用戶登錄
  2. 用戶注冊

確認項目需求要素


 

  1. 資源路徑(/users)
  2. HTTP動詞(POST)
  3. 狀態碼(200,204,400,401,403,404,405,500)
  4. 錯誤處理(輸出JSON格式錯誤信息)
  5. 返回結果(輸出JSON數組或JSON對象)

數據庫設計


 

用戶登錄和注冊業務邏輯設計


 

lib/db.php(連接數據庫)

1 <?php 
2 // 鏈接數據庫
3 $pdo=new PDO("mysql:host=localhost;dbname=api","root","");
4 // 設置字符集編碼
5 $pdo->exec("set names utf8");
6 return $pdo;
7  ?>

lib/ErrorCode.php

 1 <?php 
 2 /**
 3  * 錯誤碼
 4  */
 5 class ErrorCode
 6 {
 7     const USERNAME_CANNOT_EMPTY=1;//用戶名不能為空
 8     const PASSWORD_CANNOT_EMPTY=2;//密碼不能為空
 9     const USERNAME_EXISTS=3;//用戶名已存在
10     const REGISTER_FAIL=4;//注冊失敗
11     const LOGIN_USERNAME_CANNOT_EMPTY=5;//登錄用戶名為空
12     const LOGIN_PASSWORD_CANNOT_EMPTY=6;//登錄密碼不能為空
13     const LOGIN_FAIL=7;//登錄失敗
14 }
15  ?>

lib/User.php

  1 <?php 
  2 // 導入錯誤碼類
  3 require_once __DIR__."/ErrorCode.php";
  4 /**
  5  * 實現用戶注冊的業務邏輯設計
  6  */
  7 class User
  8 {
  9     //屬性
 10     private $_db;//存儲pdo
 11     /**
 12      * 屬性賦值
 13      * @param [type] $_db [description]
 14      */
 15     public function __construct($_db)
 16     {
 17         $this->_db=$_db;
 18     }
 19     /**
 20      * 登錄的方法
 21      * @param  [type] $username 登錄用戶名
 22      * @param  [type] $password 登錄密碼
 23      * @return array           [description]
 24      */
 25     public function login($username,$password)
 26     {
 27         // 1.檢測是否能接收到數據
 28         // echo $username.$password;
 29         // 判斷登錄的用戶名是否為空
 30         if (empty($username)) {
 31             throw new Exception("用戶名為空",ErrorCode::LOGIN_USERNAME_CANNOT_EMPTY);
 32         }
 33         // 判斷登錄密碼是否為空
 34         if (empty($password)) {
 35             throw new Exception("密碼為空",ErrorCode::LOGIN_PASSWORD_CANNOT_EMPTY);
 36         }
 37         $sql="select * from users where username=:username and password=:password";
 38         // 密碼加密
 39         $password=$this->_md5($password);
 40         // 預處理
 41         $list1=$this->_db->prepare($sql);
 42         // 綁定參數
 43         $list1->bindParam("username",$username);
 44         $list1->bindParam("password",$password);
 45         // 執行
 46         $list1->execute();
 47         // 獲取結果集
 48         $user=$list1->fetch(PDO::FETCH_ASSOC);
 49         if (empty($user)) {
 50             throw new Exception("登錄的用戶名或密碼有誤",ErrorCode::LOGIN_FAIL);
 51         }
 52         return $user;
 53     }
 54     /**
 55      * 注冊方法
 56      * @param  [type] $username [注冊用戶名]
 57      * @param  [type] $password 注冊密碼
 58      * @return array           返回注冊成功后的數據
 59      */
 60     public function register($username,$password)
 61     {
 62         // 1.測試是否調用成功
 63         // echo "this is register";
 64         // 2.測試$_db屬性是否賦值成功
 65         // echo "<pre>";
 66         // var_dump($this->_db);
 67         // 3.測試是否接收到$username和$password
 68         // echo $username.$password;
 69         // 4.把接收到的$username和$password寫入到users庫
 70         // 判斷注冊的用戶名是否為空
 71         if (empty($username)) {
 72             // 如果用戶名為空拋出異常, 第一個參數返回信息,第二個參數為狀態碼(ErrorCode類里的USERNAME_CONNOT_EMPTY靜態屬性)
 73             throw new Exception("用戶名不能為空",ErrorCode::USERNAME_CANNOT_EMPTY);
 74         }
 75         // 判斷密碼是否為空
 76         if (empty($password)) {
 77             throw new Exception("密碼不能為空",ErrorCode::PASSWORD_CANNOT_EMPTY);
 78         }
 79         // 判斷注冊的用戶名是否已存在
 80         if ($this->isUsernameExists($username)) {
 81             throw new Exception("用戶名已經注冊",ErrorCode::USERNAME_EXISTS);
 82         }
 83         // 入庫
 84         $sql="insert into users (username,password,created_at)values(:username,:password,:created_at)";
 85         // 處理接收到的數據
 86         $created_at=time();
 87         $password=$this->_md5($password);
 88         // 返回預處理
 89         $list=$this->_db->prepare($sql);
 90         // 綁定參數
 91         $list->bindParam("username",$username);
 92         $list->bindParam("password",$password);
 93         $list->bindParam("created_at",$created_at);
 94         // 判斷執行是否成功
 95         if (!$list->execute()) {
 96             throw new Exception("注冊失敗",ErrorCode::REGISTER_FAIL);
 97         }
 98         // 返回數據
 99         return [
100             'user_id'=>$this->_db->lastInsertId(),
101             'username'=>$username,
102             'created_at'=>$created_at
103         ];
104 
105     }
106     /**
107      * 檢測用戶名是否已存在的方法
108      * @param  [type]  $username [description]
109      * @return boolean           [description]
110      */
111     public function isUsernameExists($username)
112     {
113         $extists=false;
114 
115         $sql="select * from users where username=:username";
116         // 返回預處理
117         $sm=$this->_db->prepare($sql);
118         //綁定參數
119         $sm->bindParam("username",$username);
120         //執行
121         $sm->execute();
122         // 獲取結果
123         $res=$sm->fetch(PDO::FETCH_ASSOC);
124         return !empty($res);
125     }
126     /**
127      * md5加密密碼
128      * @param  [type] $string [description]
129      * @return [type]         [description]
130      */
131     public function _md5($string)
132     {
133         return md5($string);
134     }
135 }
136 
137  ?>

index.php

 1 <?php 
 2 // 導入User.php
 3 require __DIR__."/lib/User.php";
 4 // 導入db.php
 5 require __DIR__."/lib/db.php";
 6 
 7 // 實例化User類   $pdo傳入連接庫
 8 $user=new User($pdo);
 9 // 調用注冊方法 實現注冊業務邏輯操作
10 // echo "<pre>";
11 // print_r($user->register("admin6","1213"));
12 
13 // 調用登錄的方法  實現登錄的業務邏輯操作
14 // $user->login("admin3","1213");
15 // 檢測是否實現登錄業務邏輯操作
16 echo "<pre>";
17 // print_r($user->login("admin4","1213"));
18  ?>

初始化參數和完善用戶登錄及注冊API


 

restful/.htaccess(用於重寫index.php)

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [L]

restful/index.php

  1 <?php 
  2 //restful的入口文件里導入用戶注冊的業務邏輯類
  3 require __DIR__."/../lib/User.php";
  4 //導入鏈接數據庫的業務類
  5 require __DIR__."/../lib/db.php";
  6  
  7 /**
  8  * 實現用戶注冊API 接口參數完善
  9  */
 10 class Restful
 11 {
 12     // 設置私有成員屬性
 13     private $_user;//User類的對象
 14     private $_requestMethod;//接口的請求方法 http動詞集合
 15     private $_resourceName;//接口的請求資源路徑 請求資源路徑集合
 16     private $_allowResource=['users'];//接口允許的請求資源路徑
 17     private $_allowRequestMethod=['GET','POST','PUT','DELETE'];//接口允許請求方法
 18     //狀態碼
 19     private $_statusCode=[
 20                 200=>'OK',
 21                 204=>'NO CONTENT',
 22                 400=>'Bad Request',//請求出了問題
 23                 401=>'request auth is valid',//請求沒有授權
 24                 403=>'forbiden',//服務器禁止訪問
 25                 404=>"Not Fond",//找不到服務器
 26                 405=>'methis is not allowed',//請求方式不允許
 27                 500=>'server Interval error',//服務器未知錯誤
 28             ];
 29     /**
 30      * 屬性賦值
 31      * @param User $_user User類約束 user實例化的對象
 32      */
 33     public function __construct(User $_user)
 34     {
 35         $this->_user=$_user;
 36     }
 37     /**
 38      * run 方法 完善用戶注冊的參數 
 39      * 資源路徑 http動詞  返回碼 返回錯誤碼 返回的響應數據
 40      * @return [type] [description]
 41      */
 42     public function run()
 43     {
 44         try {
 45             // 調用初始化請求方法
 46             $this->_setupRequestMethod();
 47             // 初始化請求資源路徑
 48             $this->_setupResource();
 49             //規定請求資源路徑   返回響應數據
 50             if ($this->_resourceName=="users") {
 51                 return $this->_json($this->_headerUser());
 52             }
 53         } catch (Exception $e) {
 54             // getMessage()獲取錯誤信息   getCode() 獲取錯誤碼
 55             $this->_json(['error'=>$e->getMessage()],$e->getCode());
 56         }
 57     }
 58     /**
 59      * 初始化請求方法
 60      * @return [type] [description]
 61      */
 62     public function _setupRequestMethod()
 63     {
 64         // echo "<pre>";
 65         // print_r($_SERVER);
 66         // 賦值請求方式
 67         $this->_requestMethod=$_SERVER['REQUEST_METHOD'];
 68         // 判斷接口的請求方法是否存在於允許的請求方法內
 69         if (!in_array($this->_requestMethod,$this->_allowRequestMethod)) {
 70             throw new Exception("請求方法不允許",405);
 71         }
 72     }
 73     /**
 74      * 初始化請求資源路徑
 75      * @return [type] [description]
 76      */
 77     public function _setupResource()
 78     {
 79         // echo "<pre>";
 80         // print_r($_SERVER);
 81         // 獲取請求資源路徑
 82         $path=$_SERVER['PATH_INFO'];
 83         // echo $path;
 84         //轉換為數組
 85         $param=explode("/",$path);
 86         // print_r($param);
 87         // 請求資源路徑
 88         $this->_resourceName=$param[1];
 89         if (!in_array($this->_resourceName, $this->_allowResource)) {
 90             throw new Exception("請求資源路徑不允許", 400);
 91         }
 92     }
 93     /**
 94      * 返回調用接口的數據(獲取客戶端提交的數據)
 95      * @return json 返回調用接口的json格式數據
 96      */
 97     public function _headerUser()
 98     {
 99         //判斷請求的方式是否為post 
100         if ($this->_requestMethod!="POST") {
101             throw new Exception("請求方式不允許",405);
102         }
103         //獲取客戶端提交的數據
104         $body=$this->_getBodyParams();
105 
106         // 獲取請求資源路徑
107         $path=$_SERVER['PATH_INFO'];
108         //轉換為數組
109         $param=explode("/",$path);
110         // 判斷是登錄還是注冊
111         if ($param[2]=="register") {
112             // 判斷用戶名不能為空
113             if (empty($body['username'])) {
114                 throw new Exception("用戶名不能為空",400);
115             }
116             // 判斷密碼不能為空
117             if (empty($body['password'])) {
118                 throw new Exception("密碼不能為空",400);
119             }
120 
121             //返回調用接口的json數據
122             return $this->_user->register($body['username'],$body['password']);
123         }elseif ($param[2]=="login") {
124             // 判斷用戶名為空
125             if (empty($body['username'])) {
126                 throw new Exception("用戶名為空",400);
127             }
128             // 判斷密碼為空
129             if (empty($body['password'])) {
130                 throw new Exception("密碼為空",400);
131             }
132             //返回登錄調用接口的json數據
133             return $this->_user->login($body['username'],$body['password']);
134         }else{
135             throw new Exception("請求資源路徑不允許",400);
136         }
137 
138         
139     }
140     /**
141      * 獲取客戶端提交的數據
142      * @return array 獲取客戶端提交的數據(username,password)
143      */
144     public function _getBodyParams()
145     {
146         $raw=file_get_contents('php://input');
147         if (empty($raw)) {
148             throw new Exception("請求參數有誤",400);
149         }
150         // 把客戶端傳遞的json格式數據轉換為數組格式
151         return json_decode($raw,true);
152     }
153     /**
154      * 轉換響應數據(響應的狀態碼)的格式
155      * @param  array  $array 具體錯誤信息
156      * @param  integer $code  具體的相應狀態碼
157      * @return [type]         [description]
158      */
159     public function _json($array,$code=0)
160     {
161         if ($code >0 && $code !== 200 && $code != 204) {
162             //把狀態碼寫入到響應頭里
163             header("HTTP/1.1 $code");
164         }
165         header("Content-type:application/json;charset=utf-8");
166         //把響應體轉換為json格式輸出    JSON_UNESCAPED_UNICODE 轉義參數 防止有特殊字符和空格出現
167         echo json_encode($array,JSON_UNESCAPED_UNICODE);
168     }
169 }
170 
171 // 實例化USer
172 $user=new User($pdo);
173 // 調用Restful類的run方法
174 $Restful=new Restful($user);
175 $Restful->run();
176 
177  ?>

 

 

注:if語句也可以換成switch語句

2020-04-07

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM