登录和注册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

 

猜你喜欢

转载自www.cnblogs.com/gumo9/p/12653740.html