一个简单的接口开发实例

一个简单的接口开发实例

文章目录

0. 写在前面

​ 此篇文章主要是通过一个简单案例的后端接口开发过程,介绍一种接口开发方式,作为笔者本人的一个阶段性接口开发学习经验总结。其中案例是一个便签的相关接口,包含对用户和便签的信息管理。因为笔者本人能力所限,难免有差错,还希望读者能够对不正确的地方进行指正。文章也可在笔者的个人博客上查看:https://blog.csdn.net/ice_bear221/article/details/125355144

1. 开发前的准备

1.1 预备知识

  1. 学习过面向对象语言的知识
  2. 学习过SQL相关的知识

说明:

​ 初学阶段不必掌握很多,遇到问题及时搜索,相关内容在附录中也有一些学习链接

1.2 开发环境

  1. 数据库使用mysql
  2. 服务器使用apache
  3. 接口语言使用php

1.3 使用软件及笔者使用版本

  1. xampp v3.2.4:集成开发环境,包含apache、mysql、php等运行环境;
  2. netbeans v12.0:项目代码编辑器
  3. postman v9.20:接口测试、api文档生成工具
  4. navicat v15:数据库图形化管理工具

说明:

​ 也可以选择其他具有上述功能的软件。

1.4 软件下载安装及使用教程

1.4.1 xampp:

https://www.freesion.com/article/952678790/

1.4.2 netbeans:

http://www.cxfeng.com/soft/79220.html

https://blog.csdn.net/weixin_34618077/article/details/115638512

1.4.3 postman:

https://blog.csdn.net/weixin_42306958/article/details/122155484

https://blog.csdn.net/H176Nhx7/article/details/120320235

1.4.4 navicat:

https://www.pianshen.com/article/8072692518/

https://www.fujieace.com/navicat/15-for-mysql.html

说明:

​ 因为笔者的电脑已经配置了一些环境,并未对上述链接内容进行验证,如果安装过程出现问题,也请自行在网上查找相关的软件安装教程。

2. 编写实例

2.1 案例说明

​ 实现一个便签程序的后端接口。

​ 用户可以进行账号注册、账号注销、登录,以及修改密码。

​ 用户登录后可以添加、删除、修改、查询便签列表、查看便签内容。

​ 便签包含标题、内容、一张图片,其中标题不能为空,内容和图片可以为空。

2.2 案例分析

2.2.1 建立数据库和数据表
- 建立项目数据库notes
- 在notes中建立两张数据表user和note,用于存储用户信息和便签信息
- user表包含(用户id,账号,密码)
- note表包含(便签id,用户id,标题,内容,图片url,创建时间)
2.2.2 需要接口
- 用户接口
	- 注册
	- 登录
	- 注销
	- 修改密码
	
- 便签接口
	- 添加便签
	- 删除便签
	= 修改便签
	- 根据用户id查询便签列表
	- 根据便签id查询便签内容

2.3 相关文档

2.3.1 数据字典
2.3.1.1 用户表(user)
字段含义类型大小是否可为空默认值说明
uid用户idint主键
account账号string11手机号
password密码string[6, 20]此处采用明文存储
2.3.1.2 便签表(note)
字段含义类型大小是否可为空默认值说明
nid便签idint主键
uid用户idint用户表外键
title标题string30
content内容string200null
imgUrl图片urlstring200null
createTime创建时间datetime创建或修改后的时间
2.3.2 接口文档
2.3.2.1 错误码
errCodeerrInfo
0成功
1请求资源不存在
2请求方法不允许
3请求资源不允许
4请求功能错误
5请求参数错误
6请求方法错误
7数据表创建出错
8sql语句执行出错
9文件类型错误
10文件大小错误
11存储文件出错
10001用户id不能为空
10002账号重复
10003缺少账号
10004两次密码不一致
10005账号或密码错误
10006用户不存在
10007密码错误
10008缺少密码
10009缺少确认密码
10010缺少新密码
10101便签id不能为空
10102缺少标题
10103便签不存在
10104缺少时间
2.3.2.2 用户功能接口
2.3.2.2.1 用户注册
- 用户注册
请求地址:http://localhost/notes/user/register
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
    "account": "12345678910",
    "password": "123456",
    "rePassword": "123456"
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "注册成功"
}

失败:
{
    "errCode": 10003,
    "errCode": "缺少账号"
}
{
    "errCode": 10004,
    "errCode": "两次密码不一致"
}
{
    "errCode": 10008,
    "errCode": "缺少密码"
}
{
    "errCode": 10009,
    "errCode": "缺少确认密码"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.2.2 用户登录
- 用户登录
请求地址:http://localhost/notes/user/login
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
    "account": "12345678910",
    "password": "123456"
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "登录成功",
    "data": {
        "uid": 1,
        "account": "12345678910"
    }
}

失败:
{
    "errCode": 10003,
    "errCode": "缺少账号"
}
{
    "errCode": 10008,
    "errCode": "缺少密码"
}
{
    "errCode": 10005,
    "errCode": "账号或密码错误"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.2.3 用户注销
- 用户注销
请求地址:http://localhost/notes/user/logout
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
	"uid": 1,
    "password": "123456"
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "注销成功",
}

失败:
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10008,
    "errCode": "缺少密码"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 10007,
    "errCode": "密码错误"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.2.4 修改密码
- 修改密码
请求地址:http://localhost/notes/user/editPass
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
	"uid": 1,
    "password": "123456",
    "rePassword": "123456",
    "newPassword": "654321"
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "修改成功",
}

失败:
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10008,
    "errCode": "缺少密码"
}
{
    "errCode": 10009,
    "errCode": "缺少确认密码"
}
{
    "errCode": 10010,
    "errCode": "缺少新密码"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 10007,
    "errCode": "密码错误"
}
{
    "errCode": 10004,
    "errCode": "两次密码不一致"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.3 便签功能接口
2.3.2.3.1 添加便签
- 添加便签
请求地址:http://localhost/notes/note/add
请求方式:POST
请求类型:content-Type:multipart/form-data
请求参数:
Content-Disposition: form-data; name="uid" 1
Content-Disposition: form-data; name="title" 这是一个标题
Content-Disposition: form-data; name="content" 这是便签内容
Content-Disposition: form-data; name="createTime" 2022-01-01 01:01:01
Content-Disposition: form-data; name="img"; filename="IMG20191125153658.jpg"
Content-Type: image/jpeg

(data)

响应参数:

成功:
{
    "errCode": 0,
    "errCode": "添加成功",
}

失败:
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 10102,
    "errCode": "缺少标题"
}
{
    "errCode": 10104,
    "errCode": "缺少时间"
}
{
    "errCode": 10,
    "errCode": "文件大小错误"
}
{
    "errCode": 9,
    "errCode": "文件类型错误"
}
{
    "errCode": 11,
    "errCode": "存储文件出错"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.3.2 删除便签
- 删除便签
请求地址:http://localhost/notes/note/delById
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
	"uid": 1,
    "nid": 1
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "删除成功",
}

失败:
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10101,
    "errCode": "便签id不能为空"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 10103,
    "errCode": "便签不存在"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.3.3 修改便签
- 修改便签
请求地址:http://localhost/notes/note/editByNId
请求方式:POST
请求类型:content-Type:multipart/form-data
请求参数:
Content-Disposition: form-data; name="uid" 1
Content-Disposition: form-data; name="nid" 1
Content-Disposition: form-data; name="title" 这是新标题
Content-Disposition: form-data; name="content" 这是新便签内容
Content-Disposition: form-data; name="createTime" 2022-01-02 10:00:00
Content-Disposition: form-data; name="img"; filename="IMG20191125153658.jpg"
Content-Type: image/jpeg

(data)

响应参数:

成功:
{
    "errCode": 0,
    "errCode": "修改成功"
}

失败:
{
    "errCode": 10101,
    "errCode": "便签id不能为空"
}
{
    "errCode": 10103,
    "errCode": "便签不存在"
}
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 10102,
    "errCode": "缺少标题"
}
{
    "errCode": 10104,
    "errCode": "缺少时间"
}
{
    "errCode": 10,
    "errCode": "文件大小错误"
}
{
    "errCode": 9,
    "errCode": "文件类型错误"
}
{
    "errCode": 11,
    "errCode": "存储文件出错"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.3.4 查询便签列表
- 查询便签列表
请求地址:http://localhost/notes/note/viewListByUid
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
	"uid": 1,
    "offset": 0,
    "limit": 20
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "查询成功",
    "data": [
        {
            "nid": 1,
            "title": "这是一个标题"
        },
        {
            "nid": 2,
            "title": "新的便签"
        }
    ]
}

失败:
{
    "errCode": 10001,
    "errCode": "用户id不能为空"
}
{
    "errCode": 10006,
    "errCode": "用户不存在"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}
2.3.2.3.5 查询便签内容
- 查询便签内容
请求地址:http://localhost/notes/note/viewByNid
请求方式:POST
请求类型:content-Type:application/json
请求参数:
{
	"nid": 1
}
响应参数:

成功:
{
    "errCode": 0,
    "errCode": "查询成功",
    "data": {
        "nid": 1,
        "title": "这是一个标题",
        "content": "这是便签内容",
        "imgUrl": "http://localhost/notes/uploads/abasdfsdf.jpg",
        "createTime": "2022-01-02 10:00:00"
    }
}

失败:
{
    "errCode": 10101,
    "errCode": "便签id不能为空"
}

{
    "errCode": 10103,
    "errCode": "便签不存在"
}
{
    "errCode": 8,
    "errCode": "sql语句执行错误"
}

2.4 项目实现

2.4.1 项目准备
2.4.1.1 启动apache和mysql

在这里插入图片描述

2.4.1.2 添加notes数据库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4.1.3 建立php项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4.1.4 添加文件夹和php文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4.1.5 添加.htaccess文件

在这里插入图片描述
在这里插入图片描述

添加如下代码:

# 开启重定向
RewriteEngine on
# 访问的不是文件
RewriteCond %{REQUEST_FILENAME} !-f
# 访问的不是文件夹
RewriteCond %{REQUEST_FILENAME} !-d
# 重定向到访问index.php文件
RewriteRule ^(.*)$ index.php/$1 [L] 

说明:

添加.htaccess文件之前的访问链接为:http://localhost/notes/index.php/user/login

添加.htaccess文件之后的访问链接为:http://localhost/notes/user/login

只要访问的内容不是文件和文件夹,都会重定向到访问:http://localhost/notes/index.php

2.4.2 配置数据库连接(conf.php, db.php)
2.4.2.1 编辑conf.php
<?php
    
// 此文件用于保存一些默认配置

define("HOST", 'localhost'); // 配置主机名,本机是localhost或127.0.0.1
define("DBNAME", "notes"); // 项目数据库名,
define("DBUSER", "root"); // 登录数据库用户名
define("DBPASS", ""); // 密码

define("VERSION", "1.0"); // 接口版本
define("DOMAIN", "http://localhost/notes"); // 项目位置

2.4.2.2 编辑db.php
<?php

require_once __DIR__."/conf.php"; // 引入conf.php文件
//
// 生成并返回数据库连接对象,用于操作数据库
$db = new PDO("mysql:host=".HOST.";dbname=".DBNAME, DBUSER, DBPASS);
return $db;

2.4.3 编辑错误码类和工具类(Errors.php, Tools.php)
2.4.3.1 编辑Errors.php
<?php

/**
 * Description of Errors
 *保存项目错误码
 * @author 1
 */
class Errors {
    // 错误码5位
    // 
    // 系统相关 0-9999
    const OK = 0;
    const REQUEST_IS_NULL = 1;
    const REQUEST_METHOD_NOT_ALLOWED = 2;
    const REQUEST_RESOUTCE_NOT_ALLOWED = 3;
    const REQUEST_FUNCTION_IS_ERROR = 4;
    const REQUEST_PARAMETER_ERROR = 5;
    const REQUEST_METHOD_IS_ERROR = 6;
    const BUILD_TABLE_ERROR = 7;
    const SQL_EXECUTE_ERROR = 8;
    const FILE_TYPE_IS_ERROR = 9;
    const FILE_SIZE_IS_ERROR = 10;
    const STORE_FILE_OCCURRED_ERROR = 11;
    
    
    // 用户类相关 10001-10099
    const USER_ID_CONNOT_NULL = 10001;
    const ACCOUNT_REPEAT = 10002;
    const ACCOUNT_IS_MISSING = 10003;
    const PASSWORD_IS_NOT_SAME = 10004;
    const ACCOUNT_OR_PASSWORD_ERROR = 10005;
    const USER_IS_NOT_EXISTS = 10006;
    const PASSWORD_IS_ERROR = 10007;
    const PASSWORD_IS_MISSING = 10008;
    const REPASSWORD_IS_MISSING = 10009;
    const NEW_PASSWORD_IS_MISSING = 10010;
    
    // 便签类相关 10101-10199
    const NOTE_ID_CONNOT_NULL = 10101;
    const TITLE_IS_MISSING = 10102;
    const NOTE_IS_NOT_EXISTS = 10103;
    const TIME_IS_MISSING = 10104;
}

2.4.3.2 编辑Tools.php
<?php

require_once 'lib/conf.php';
/**
 * Description of Tools
 * 封装较常用的函数
 * @author 1
 */
class Tools {
    /**
     * 打印调试信息
     * @param type $message print info
     */
    public static function _debug($message) {
        var_dump($message);
    }
    
    /**
     * 打印json格式信息
     * @param type $errInfo 返回信息
     * @param type $errCode 返回信息提示码
     * @param type $data 返回数据
     */
    public static function printJson($errInfo, $errCode, $data=null) {
        $return["errCode"] = $errCode;
        $return["errInfo"] = $errInfo;
        if (!empty($data))
            $return["data"] = $data;
        else if (!is_null($data))
        {
            $return["data"] = [];
        }
        
        header("Content-Type:application/json;charset:utf-8");
        echo json_encode($return, JSON_PRETTY_PRINT + JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);
    }
    
    /**
     * 根据检查条件和所给文件类型判断文件是够可接受
     * @param string $type
     * @param int $flag
     * @return bool
     */
    public static function checkFileType($type, $flag) {
        $allowImgType = ["jpg", "jpeg", "png", "bmp"];
        $allowDocType = ["doc", "docx", "ppt", "pptx", "xls", "xlsx", "txt"];
        $allowType = ["jpg", "jpeg", "png", "bmp", 
            "doc", "docx", "ppt", "pptx", "xls", "xlsx", 
            "zip", "7z", "rar", "txt"];
        if ($flag == 0) {
            // 是否满足可接受的所有文件类型
            return in_array($type, $allowType);
        }
        else if ($flag == 1) {
            // 是否满足可接受的图片类型
            return in_array($type, $allowImgType);
        }
    }
    
    /**
     * 检查文件大小是否满足条件
     * @param int $fileSize 待检查文件大小
     * @param int $allowSize 可接受大小
     * @return type
     */
    public static function checkFileSize($fileSize, $allowSize) {
        return $fileSize <= $allowSize;
    }
    
    /**
     * 创建多级文件夹
     * @param type $dirName
     */
    public static function createDir($dirName) {
        if (!file_exists("$dirName")) {
            mkdir($dirName, 0777, true);
        }
    }
    
    /**
     * 存储文件,返回文件url
     * @param string $fileDir 文件存储路径
     * @param string $filename 临时文件地址
     * @param string $fileType 文件类型
     * @return string
     */
    public static function storeFile($fileDir, $filename, $fileType) {
        // 生成文件路径
        $filePath = $fileDir."/".md5($filename).".".$fileType;
        
        // 将临时文件存入目标路径
        if (!move_uploaded_file($filename, $filePath)) {
            // 存储失败后返回空
            return null;
        }
        else {
            // 存储成功
            $url = DOMAIN."/".$filePath;
            return $url;
        }
    }
}

2.4.4 编辑启动类(Rest.php)
2.4.4.1 编辑Rest.php
<?php

require_once __DIR__.'/Errors.php';
require_once __DIR__.'/Tools.php';
/**
 * Description of Rest
 *
 * @author 1
 */
class Rest {
    // 设置允许的请求方法和资源
    private $_allowMethod = ["GET", "POST"];
    private $_allowResource = ["user", "note"];
    
    // 请求的方法、资源、功能
    private $_requestMethod;
    private $_requestResource;
    private $_requestFunction;
    
    // 资源类对象
    private $_db;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db) {
        $this->_db = $db;
    }
    
    /**
     * api启动方法
     */
    public function run() {
        try {
            // 获取并检查请求的方法和资源
            $this->setRequestMethod();
            $this->setRequestResource();
            
            // 根据请求的资源分发请求,交给对应的资源类处理
            switch ($this->_requestResource) {
                
                default : {
                    Tools::printJson("请求内容为空", Errors::REQUEST_IS_NULL);
                }
            }
        } catch (Exception $exc) {
            Tools::printJson($exc->getMessage(), $exc->getCode());
        }
    }

    /**
     * 获取post提交的数据
     * @return type array
     * @throws Exception 请求参数错误
     */
    private function getBody() {
        // 获取post请求提交的信息
        $postData = file_get_contents("PHP://input");
        
        // post请求提交的参数不能为空
        if (empty($postData))
        {
            throw new Exception("请求参数错误", Errors::REQUEST_PARAMETER_ERROR);
        }
        
        // 将获取的请求参数进行json解码,用于后续操作
        return json_decode($postData, true);
    }
    
    /**
     * 获取并检查请求的方法
     * @throws Exception 请求方法不被允许
     */
    private function setRequestMethod() {
        // 获取请求方法
        $this->_requestMethod = $_SERVER["REQUEST_METHOD"];
        
        // 检查请求方法是否被允许
        if (!in_array($this->_requestMethod, $this->_allowMethod))
        {
            throw new Exception("请求方法不被允许", Errors::REQUEST_METHOD_NOT_ALLOWED);
        }
    }
    
    /**
     * 获取请求的资源、功能
     * @throws Exception 请求资源不被允许
     */
    private function setRequestResource() {
        // 若访问的rl为http://localhost/notes/user/login,则$_SERVER["PATH_INFO"]为 /user/login
        $path = $_SERVER["PATH_INFO"];
        $params = explode('/', $path);

        $this->_requestResource = $params[1];
        if (!in_array($this->_requestResource, $this->_allowResource))
        {
            throw new Exception("请求资源不被允许", Errors::REQUEST_RESOUTCE_NOT_ALLOWED);
        }
        
        if (!empty($params[2]))
        {
            $this->_requestFunction = $params[2];
        }
    }
}

2.4.5 编辑api启动文件index.php
2.4.5.1 编辑index.php
<?php

// 下面引入资源类
require_once './class/Rest.php';

// 下面创建资源对象
$db = require_once './lib/db.php';

// 创建启动类对象,并启动
$api = new Rest($db);
$api->run();
2.4.6 编辑用户类(User.php)

说明:

笔者这里为了方便,没有依次介绍每个功能的编写以及测试,而是将所有的内容放在一起,读者练习时可以在写完一个功能后,先看后面的接口测试,检验接口情况。

2.4.6.1 添加User类并编写基本内容

在这里插入图片描述

<?php

/**
 * Description of User
 * 用户类功能
 * @author 1
 */
class User {
    private $_db;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db) {
        $this->_db = $db;
    }
}

2.4.6.2 User.php添加相关功能函数后
<?php

/**
 * Description of User
 * 用户类功能
 * @author 1
 */
class User {
    private $_db;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db) {
        $this->_db = $db;
    }
    
    /**
     * 创建数据表
     */
    public function buildDb() {
        // 建立用户表
        
        // 检查notes数据库中是否包含user表
        $sql = "select count(1) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='notes' and TABLE_NAME='user'";
        $sm = $this->_db->prepare($sql);

        // 执行sql语句
        if ($sm->execute()) {
            // 获取执行结果
            $re = $sm->fetch(PDO::FETCH_COLUMN);
            
            //    表不存在,开始建立
            if (!$re) {
                $sql = "create table user  (
                        uId int primary key not null auto_increment comment '用户id',
                        account varchar(11) unique not null comment '手机号',
                        password varchar(20) not null comment '密码'
                      )";
                $sm = $this->_db->prepare($sql);
                if ($sm->execute()) {
                    Tools::printJson("建表成功", Errors::OK);
                } else {
                    Tools::printJson("建表失败", Errors::BUILD_TABLE_ERROR);
                }
            }
            else {
                Tools::printJson("表已经存在", Errors::OK);
            }
        } else {
            Tools::printJson("sql语句执行失败", Errors::SQL_EXECUTE_ERROR);
        }
    }
    
    /**
     * 用户注册
     * @param Object $postData
     * @throws Exception
     */
    public function register($postData) {
        // 检查参数
        if (!key_exists("account", $postData) || empty($postData["account"])) {
            throw new Exception("缺少账号", Errors::ACCOUNT_IS_MISSING);
        }
        if (!key_exists("password", $postData) || empty($postData["password"])) {
            throw new Exception("缺少密码", Errors::PASSWORD_IS_MISSING);
        }
        if (!key_exists("rePassword", $postData) || empty($postData["rePassword"])) {
            throw new Exception("缺少确认密码", Errors::REPASSWORD_IS_MISSING);
        }
        if (!($postData["password"] === $postData["rePassword"])) {
            throw new Exception("两次密码不一致", Errors::PASSWORD_IS_NOT_SAME);
        }
        
        // 将用户信息添加进数据库
        // 注意在每行结尾的"前添加空格,否则可能导致sql语句执行错误
        $sql = "insert into user(account, password) "
                . "values(:account, :password) ";
        
        // 进行预处理
        $sm = $this->_db->prepare($sql);
        
        // 绑定数据
        $sm->bindParam(":account", $postData["account"]);
        $sm->bindParam(":password", $postData["password"]);
        
        // 执行sql语句
        if (!$sm->execute()) {
            throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            Tools::printJson("注册成功", Errors::OK);
        }
    }
    
    /**
     * 用户登录
     * @param type $postData
     * @throws Exception
     */
    public function login($postData) {
        // 检查参数
        if (!key_exists("account", $postData) || empty($postData["account"])) {
            throw new Exception("缺少账号", Errors::ACCOUNT_IS_MISSING);
        }
        if (!key_exists("password", $postData) || empty($postData["password"])) {
            throw new Exception("缺少密码", Errors::PASSWORD_IS_MISSING);
        }
        
        // 查询数据库信息
        $sql = "select uid, account from user "
                . "where account = :account "
                . "and password = :password ";
        
        // 进行预处理
        $sm = $this->_db->prepare($sql);
        
        // 绑定数据
        $sm->bindParam(":account", $postData["account"]);
        $sm->bindParam(":password", $postData["password"]);
        
        // 执行sql语句
        if (!$sm->execute()) {
            throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            // 获取查询结果
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            // 检查结果并返回信息
            if (empty($returnData)) {
                throw new Exception("账号或密码错误", Errors::ACCOUNT_OR_PASSWORD_ERROR);
            }
            else {
                Tools::printJson("登录成功", Errors::OK, $returnData);
            }
        }
    }
    
    /**
     * 修改密码
     * @param type $postData
     * @throws Exception
     */
    public function editPass($postData) {
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("password", $postData) || empty($postData["password"])) {
            throw new Exception("缺少密码", Errors::PASSWORD_IS_MISSING);
        }
        if (!key_exists("rePassword", $postData) || empty($postData["rePassword"])) {
            throw new Exception("缺少确认密码", Errors::REPASSWORD_IS_MISSING);
        }
        if (!key_exists("newPassword", $postData) || empty($postData["newPassword"])) {
            throw new Exception("缺少新密码", Errors::NEW_PASSWORD_IS_MISSING);
        }
        if (!($postData["password"] === $postData["rePassword"])) {
            throw new Exception("两次密码不一致", Errors::PASSWORD_IS_NOT_SAME);
        }
        
        // 判断用户是否存在,以及查询原密码进行比对
        $sql = "select password from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            // 检查用户信息
            if (empty($returnData)) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
            else {
                if (!($postData["password"] === $returnData["password"])) {
                    throw new Exception("密码错误", Errors::PASSWORD_IS_ERROR);
                }
                else {
                    // 更新用户密码
                    $sql = "update user set password = :newPassword "
                            . "where uid = :uid ";
                    $sm = $this->_db->prepare($sql);
                    $sm->bindParam(":uid", $postData["uid"]);
                    $sm->bindParam(":newPassword", $postData["newPassword"]);
                    
                    if (!$sm->execute()) {
                        throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
                    }
                    else {
                        Tools::printJson("修改成功", Errors::OK);
                    }
                }
            }
        }
    }
    
    /**
     * 用户注销
     * @param type $postData
     * @throws Exception
     */
    public function logout($postData) {
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("password", $postData) || empty($postData["password"])) {
            throw new Exception("缺少密码", Errors::PASSWORD_IS_MISSING);
        }
        
        // 判断用户是否存在,以及查询原密码进行比对
        $sql = "select password from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            // 检查用户信息
            if (empty($returnData)) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
            else {
                if (!($postData["password"] === $returnData["password"])) {
                    throw new Exception("密码错误", Errors::PASSWORD_IS_ERROR);
                }
                else {
                    // 开启事务,保证下面的sql语句全部执行正确后才修改数据库内容
                    $this->_db->beginTransaction();
                    
                    // 删除用户发布的所有便签,此时还没有添加note数据表,可以先忽略
                    /*
                    $sql = "delete from note where uid = :uid ";
                    $sm = $this->_db->prepare($sql);
                    $sm->bindParam(":uid", $postData["uid"]);
                    
                    if (!$sm->execute()) {
                        // 数据库回滚
                        $this->_db->rollBack();
                        
                        throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
                    }
                     * 
                     */
                    
                    // 删除用户
                    $sql = "delete from user where uid = :uid ";
                    $sm = $this->_db->prepare($sql);
                    $sm->bindParam(":uid", $postData["uid"]);
                    
                    if (!$sm->execute()) {
                        // 数据库回滚
                        $this->_db->rollBack();
                        
                        throw new Exception("sql语句执行错误", Errors::SQL_EXECUTE_ERROR);
                    }
                    else {
                        // 提交数据库操作
                        $this->_db->commit();
                        
                        Tools::printJson("注销成功", Errors::OK);
                    }
                }
            }
        }
    }
}

2.4.6.3 修改index.php文件
<?php

// 下面引入资源类
require_once './class/Rest.php';
require_once './class/User.php';    // 引入User类

// 下面创建资源对象
$db = require_once './lib/db.php';
$user = new User($db);  // 创建User资源类对象

// 创建启动类对象,并启动
$api = new Rest($db, $user);
$api->run();
2.4.6.4 修改Rest.php文件
<?php

require_once __DIR__.'/Errors.php';
require_once __DIR__.'/Tools.php';
/**
 * Description of Rest
 *
 * @author 1
 */
class Rest {
    // 设置允许的请求方法和资源
    private $_allowMethod = ["GET", "POST"];
    private $_allowResource = ["user", "note"];
    
    // 请求的方法、资源、功能
    private $_requestMethod;
    private $_requestResource;
    private $_requestFunction;
    
    // 资源类对象
    private $_db;
    private $_user;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db, User $user) {
        $this->_db = $db;
        $this->_user = $user;
    }
    
    /**
     * api启动方法
     */
    public function run() {
        try {
            // 获取并检查请求的方法和资源
            $this->setRequestMethod();
            $this->setRequestResource();
            
            // 根据请求的资源分发请求,交给对应的资源类处理
            switch ($this->_requestResource) {
                case "user": {
                    $this->sendUser();
                    break;
                }
                default : {
                    Tools::printJson("请求内容为空", Errors::REQUEST_IS_NULL);
                }
            }
        } catch (Exception $exc) {
            Tools::printJson($exc->getMessage(), $exc->getCode());
        }
    }
    
    
    /**
     * 处理用户业务
     * @throws Exception
     */
    private function sendUser() {
        switch ($this->_requestMethod) {
            case "POST": {
                switch ($this->_requestFunction) {
                    case "buildDb": {
                        $this->_user->buildDb();
                        break;
                    }
                    case "register": {
                        $this->_user->register($this->getBody());
                        break;
                    }
                    case "login": {
                        $this->_user->login($this->getBody());
                        break;
                    }
                    case "editPass": {
                        $this->_user->editPass($this->getBody());
                        break;
                    }
                    case "logout": {
                        $this->_user->logout($this->getBody());
                        break;
                    }
                    default : {
                        Tools::printJson("请求功能不存在", Errors::REQUEST_FUNCTION_IS_ERROR);
                    }
                }
                break;
            }
            default: {
                throw new Exception("该资源没有此方法的接口", Errors::REQUEST_METHOD_IS_ERROR);
            }
        }
    }

    /**
     * 获取post提交的数据
     * @return type array
     * @throws Exception 请求参数错误
     */
    private function getBody() {
        // 获取post请求提交的信息
        $postData = file_get_contents("PHP://input");
        
        // post请求提交的参数不能为空
        if (empty($postData))
        {
            throw new Exception("请求参数错误", Errors::REQUEST_PARAMETER_ERROR);
        }
        
        // 将获取的请求参数进行json解码,用于后续操作
        return json_decode($postData, true);
    }
    
    /**
     * 获取并检查请求的方法
     * @throws Exception 请求方法不被允许
     */
    private function setRequestMethod() {
        // 获取请求方法
        $this->_requestMethod = $_SERVER["REQUEST_METHOD"];
        
        // 检查请求方法是否被允许
        if (!in_array($this->_requestMethod, $this->_allowMethod))
        {
            throw new Exception("请求方法不被允许", Errors::REQUEST_METHOD_NOT_ALLOWED);
        }
    }
    
    /**
     * 获取请求的资源、功能
     * @throws Exception 请求资源不被允许
     */
    private function setRequestResource() {
        // 若访问的rl为http://localhost/notes/user/login,则$_SERVER["PATH_INFO"]为 /user/login
        $path = $_SERVER["PATH_INFO"];
        $params = explode('/', $path);

        $this->_requestResource = $params[1];
        if (!in_array($this->_requestResource, $this->_allowResource))
        {
            throw new Exception("请求资源不被允许", Errors::REQUEST_RESOUTCE_NOT_ALLOWED);
        }
        
        if (!empty($params[2]))
        {
            $this->_requestFunction = $params[2];
        }
    }
}

2.4.7 编写便签类(Note.php)
2.4.7.1 添加Note类并编写基本内容

在这里插入图片描述

<?php

/**
 * Description of Note
 * 便签类功能
 * @author 1
 */
class Note {
    private $_db;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db) {
        $this->_db = $db;
    }
}

2.4.7.2 Note.php添加相关功能函数
<?php

/**
 * Description of Note
 * 便签类功能
 * @author 1
 */
class Note {
    private $_db;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db) {
        $this->_db = $db;
    }
    
    /**
     * 创建数据表
     */
    public function buildDb() {
        // 建立便签表
        
        // 检查notes数据库中是否包含note表
        $sql = "select count(1) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='notes' and TABLE_NAME='note'";
        $sm = $this->_db->prepare($sql);

        // 执行sql语句
        if ($sm->execute()) {
            // 获取执行结果
            $re = $sm->fetch(PDO::FETCH_COLUMN);
            
            //    表不存在,开始建立
            if (!$re) {
                $sql = "create table note  (
                        nid int primary key not null auto_increment comment '便签id',
                        uid int not null comment '用户id',
                        title varchar(30) not null comment '标题',
                        content varchar(200) null comment '内容',
                        imgUrl varchar(200) null comment '图片url',
                        createTime datetime not null comment '创建或修改后的时间',
                        foreign key(uid) references user(uid)
                      )";
                $sm = $this->_db->prepare($sql);
                if ($sm->execute()) {
                    Tools::printJson("建表成功", Errors::OK);
                } else {
                    Tools::printJson("建表失败", Errors::BUILD_TABLE_ERROR);
                }
            }
            else {
                Tools::printJson("表已经存在", Errors::OK);
            }
        } else {
            Tools::printJson("sql语句执行失败", Errors::SQL_EXECUTE_ERROR);
        }
    }
    
    /**
     * 添加便签
     * @throws Exception
     */
    public function add() {
        // 获取请求参数
        $postData = $_POST;
        $fileData = $_FILES;
        
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("title", $postData) || empty($postData["title"])) {
            throw new Exception("缺少标题", Errors::TITLE_IS_MISSING);
        }
        if (!key_exists("createTime", $postData) || empty($postData["createTime"])) {
            throw new Exception("缺少时间", Errors::TIME_IS_MISSING);
        }
        
        // 检查用户是否存在
        $sql = "select count(1) 'count' from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
        }
        
        // 如果含有图片,先保存到文件夹内
        if (!key_exists("img", $fileData) || empty($fileData["img"]) || $fileData["img"]["size"] == 0) {
            $postData["imgUrl"] = null;
        }
        else {
            // 存储图片
            // 检查图片类型
            $type = explode(".", $fileData["img"]["name"]);
            $fileType = $type[count($type) - 1];
            if (!Tools::checkFileType($fileType, 1)) {
                throw new Exception("文件类型错误", Errors::FILE_TYPE_IS_ERROR);
            }
            
            // 检查图片大小,<=8M
            if (!Tools::checkFileSize($fileData["img"]["size"], 8388608)) {
                throw new Exception("文件大小错误", Errors::FILE_SIZE_IS_ERROR);
            }
            
            // 创建图片文件夹,存储图片
            $fileDir = "uploads/img";
            Tools::createDir($fileDir);
            $url = Tools::storeFile($fileDir, $fileData["img"]["tmp_name"], $fileType);
            if (is_null($url)) {
                throw new Exception("存储文件出错", Errors::STORE_FILE_OCCURRED_ERROR);
            }
            $postData["imgUrl"] = $url;
        }
        
        // 保存信息到数据库
        $sql = "insert into note(uid, title, content, createTime, imgUrl) "
                . "values(:uid, :title, :content, :createTime, :imgUrl) ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        $sm->bindParam(":title", $postData["title"]);
        $sm->bindParam(":content", $postData["content"]);
        $sm->bindParam(":createTime", $postData["createTime"]);
        $sm->bindParam(":imgUrl", $postData["imgUrl"]);
        
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            Tools::printJson("添加成功", Errors::OK);
        }
    }
    
    /**
     * 修改便签
     * @throws Exception
     */
    public function editByNid() {
        // 获取请求参数
        $postData = $_POST;
        $fileData = $_FILES;
        
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("nid", $postData) || empty($postData["nid"])) {
            throw new Exception("便签id不能为空", Errors::NOTE_ID_CONNOT_NULL);
        }
        if (!key_exists("title", $postData) || empty($postData["title"])) {
            throw new Exception("缺少标题", Errors::TITLE_IS_MISSING);
        }
        if (!key_exists("createTime", $postData) || empty($postData["createTime"])) {
            throw new Exception("缺少时间", Errors::TIME_IS_MISSING);
        }
        
        // 检查用户是否存在
        $sql = "select count(1) 'count' from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
        }
        
        // 检查便签是否存在
        $sql = "select count(1) 'count' from note "
                . "where uid = :uid "
                . "and nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        $sm->bindParam(":nid", $postData["nid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("便签不存在", Errors::NOTE_IS_NOT_EXISTS);
            }
        }
        
        // 如果含有图片,先保存到文件夹内
        if (!key_exists("img", $fileData) || empty($fileData["img"]) || $fileData["img"]["size"] == 0) {
            $postData["imgUrl"] = null;
        }
        else {
            // 存储图片
            // 检查图片类型
            $type = explode(".", $fileData["img"]["name"]);
            $fileType = $type[count($type) - 1];
            if (!Tools::checkFileType($fileType, 1)) {
                throw new Exception("文件类型错误", Errors::FILE_TYPE_IS_ERROR);
            }
            
            // 检查图片大小,<=8M
            if (!Tools::checkFileSize($fileData["img"]["size"], 8388608)) {
                throw new Exception("文件大小错误", Errors::FILE_SIZE_IS_ERROR);
            }
            
            // 创建图片文件夹,存储图片
            $fileDir = "uploads/img";
            Tools::createDir($fileDir);
            $url = Tools::storeFile($fileDir, $fileData["img"]["tmp_name"], $fileType);
            if (is_null($url)) {
                throw new Exception("存储文件出错", Errors::STORE_FILE_OCCURRED_ERROR);
            }
            $postData["imgUrl"] = $url;
        }
        
        // 保存信息到数据库
        $sql = "update note set title = :title, content = :content, "
                . "createTime = :createTime, imgUrl = :imgUrl "
                . "where nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":nid", $postData["nid"]);
        $sm->bindParam(":title", $postData["title"]);
        $sm->bindParam(":content", $postData["content"]);
        $sm->bindParam(":createTime", $postData["createTime"]);
        $sm->bindParam(":imgUrl", $postData["imgUrl"]);
        
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            Tools::printJson("修改成功", Errors::OK);
        }
    }
    
    /**
     * 查询便签列表
     * @param type $postData
     * @throws Exception
     */
    public function viewListByUid($postData) {
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("offset", $postData) || empty($postData["offset"])) {
            $postData["offset"] = 0;
        }
        if (!key_exists("limit", $postData) || empty($postData["limit"]) 
                || $postData["limit"] > 20) {
            $postData["limit"] = 20;
        }
        
        // 检查用户是否存在
        $sql = "select count(1) 'count' from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
        }
        
        // 查询便签列表
        $sql = "select nid, title from note "
                . "where uid = :uid "
                . "limit :offset, :limit ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        $sm->bindParam(":offset", $postData["offset"], PDO::PARAM_INT);
        $sm->bindParam(":limit", $postData["limit"], PDO::PARAM_INT);
        
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetchAll(PDO::FETCH_ASSOC);
            
            Tools::printJson("查询成功", Errors::OK, $returnData);
        }
    }
    
    /**
     * 查询便签内容
     * @param type $postData
     * @throws Exception
     */
    public function viewByNid($postData) {
        // 检查参数
        if (!key_exists("nid", $postData) || empty($postData["nid"])) {
            throw new Exception("便签id不能为空", Errors::NOTE_ID_CONNOT_NULL);
        }
        
        // 检查便签是否存在
        $sql = "select count(1) 'count' from note "
                . "where nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":nid", $postData["nid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("便签不存在", Errors::NOTE_IS_NOT_EXISTS);
            }
        }
        
        // 查询便签内容
        $sql = "select nid, title, content, imgUrl, createTime from note "
                . "where nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":nid", $postData["nid"]);
        
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            Tools::printJson("查询成功", Errors::OK, $returnData);
        }
    }
    
    /**
     * 删除便签
     * @param type $postData
     * @throws Exception
     */
    public function delById($postData) {
        // 检查参数
        if (!key_exists("uid", $postData) || empty($postData["uid"])) {
            throw new Exception("用户id不能为空", Errors::USER_ID_CONNOT_NULL);
        }
        if (!key_exists("nid", $postData) || empty($postData["nid"])) {
            throw new Exception("便签id不能为空", Errors::NOTE_ID_CONNOT_NULL);
        }
        
        // 检查用户是否存在
        $sql = "select count(1) 'count' from user "
                . "where uid = :uid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("用户不存在", Errors::USER_IS_NOT_EXISTS);
            }
        }
        
        // 检查便签是否存在
        $sql = "select count(1) 'count' from note "
                . "where uid = :uid "
                . "and nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        $sm->bindParam(":nid", $postData["nid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            $returnData = $sm->fetch(PDO::FETCH_ASSOC);
            
            if (empty($returnData["count"])) {
                throw new Exception("便签不存在", Errors::NOTE_IS_NOT_EXISTS);
            }
        }
        
        // 删除便签
        $sql = "delete from note "
                . "where uid = :uid "
                . "and nid = :nid ";
        $sm = $this->_db->prepare($sql);
        $sm->bindParam(":uid", $postData["uid"]);
        $sm->bindParam(":nid", $postData["nid"]);
        if (!$sm->execute()) {
            throw new Exception("sql语句执行出错", Errors::SQL_EXECUTE_ERROR);
        }
        else {
            Tools::printJson("删除成功", Errors::OK);
        }
    }
}

2.4.7.3 修改index.php文件
<?php

// 下面引入资源类
require_once './class/Rest.php';
require_once './class/User.php';    // 引入User类
require_once './class/Note.php';    // 引入Note类
//
// 下面创建资源对象
$db = require_once './lib/db.php';
$user = new User($db);  // 创建User资源类对象
$note = new Note($db);  // 创建Note资源类对象

// 创建启动类对象,并启动
$api = new Rest($db, $user, $note);
$api->run();
2.4.7.4 修改Rest.php文件
<?php

require_once __DIR__.'/Errors.php';
require_once __DIR__.'/Tools.php';
/**
 * Description of Rest
 *
 * @author 1
 */
class Rest {
    // 设置允许的请求方法和资源
    private $_allowMethod = ["GET", "POST"];
    private $_allowResource = ["user", "note"];
    
    // 请求的方法、资源、功能
    private $_requestMethod;
    private $_requestResource;
    private $_requestFunction;
    
    // 资源类对象
    private $_db;
    private $_user;
    private $_note;
    
    /**
     * 构造函数
     * @param PDO $db
     */
    public function __construct(PDO $db, User $user, Note $note) {
        $this->_db = $db;
        $this->_user = $user;
        $this->_note = $note;
    }
    
    /**
     * api启动方法
     */
    public function run() {
        try {
            // 获取并检查请求的方法和资源
            $this->setRequestMethod();
            $this->setRequestResource();
            
            // 根据请求的资源分发请求,交给对应的资源类处理
            switch ($this->_requestResource) {
                case "user": {
                    $this->sendUser();
                    break;
                }
                case "note": {
                    $this->sendNote();
                    break;
                }
                default : {
                    Tools::printJson("请求内容为空", Errors::REQUEST_IS_NULL);
                }
            }
        } catch (Exception $exc) {
            Tools::printJson($exc->getMessage(), $exc->getCode());
        }
    }
    
    /**
     * 处理便签业务
     * @throws Exception
     */
    private function sendNote() {
        switch ($this->_requestMethod) {
            case "POST": {
                switch ($this->_requestFunction) {
                    case "buildDb": {
                        $this->_note->buildDb();
                        break;
                    }
                    case "add": {
                        $this->_note->add();
                        break;
                    }
                    case "editByNid": {
                        $this->_note->editByNid();
                        break;
                    }
                    case "viewListByUid": {
                        $this->_note->viewListByUid($this->getBody());
                        break;
                    }
                    case "viewByNid": {
                        $this->_note->viewByNid($this->getBody());
                        break;
                    }
                    case "delById": {
                        $this->_note->delById($this->getBody());
                        break;
                    }
                    default : {
                        Tools::printJson("请求功能不存在", Errors::REQUEST_FUNCTION_IS_ERROR);
                    }
                }
                break;
            }
            default: {
                throw new Exception("该资源没有此方法的接口", Errors::REQUEST_METHOD_IS_ERROR);
            }
        }
    }
    
    
    /**
     * 处理用户业务
     * @throws Exception
     */
    private function sendUser() {
        switch ($this->_requestMethod) {
            case "POST": {
                switch ($this->_requestFunction) {
                    case "buildDb": {
                        $this->_user->buildDb();
                        break;
                    }
                    case "register": {
                        $this->_user->register($this->getBody());
                        break;
                    }
                    case "login": {
                        $this->_user->login($this->getBody());
                        break;
                    }
                    case "editPass": {
                        $this->_user->editPass($this->getBody());
                        break;
                    }
                    case "logout": {
                        $this->_user->logout($this->getBody());
                        break;
                    }
                    default : {
                        Tools::printJson("请求功能不存在", Errors::REQUEST_FUNCTION_IS_ERROR);
                    }
                }
                break;
            }
            default: {
                throw new Exception("该资源没有此方法的接口", Errors::REQUEST_METHOD_IS_ERROR);
            }
        }
    }

    /**
     * 获取post提交的数据
     * @return type array
     * @throws Exception 请求参数错误
     */
    private function getBody() {
        // 获取post请求提交的信息
        $postData = file_get_contents("PHP://input");
        
        // post请求提交的参数不能为空
        if (empty($postData))
        {
            throw new Exception("请求参数错误", Errors::REQUEST_PARAMETER_ERROR);
        }
        
        // 将获取的请求参数进行json解码,用于后续操作
        return json_decode($postData, true);
    }
    
    /**
     * 获取并检查请求的方法
     * @throws Exception 请求方法不被允许
     */
    private function setRequestMethod() {
        // 获取请求方法
        $this->_requestMethod = $_SERVER["REQUEST_METHOD"];
        
        // 检查请求方法是否被允许
        if (!in_array($this->_requestMethod, $this->_allowMethod))
        {
            throw new Exception("请求方法不被允许", Errors::REQUEST_METHOD_NOT_ALLOWED);
        }
    }
    
    /**
     * 获取请求的资源、功能
     * @throws Exception 请求资源不被允许
     */
    private function setRequestResource() {
        // 若访问的rl为http://localhost/notes/user/login,则$_SERVER["PATH_INFO"]为 /user/login
        $path = $_SERVER["PATH_INFO"];
        $params = explode('/', $path);

        $this->_requestResource = $params[1];
        if (!in_array($this->_requestResource, $this->_allowResource))
        {
            throw new Exception("请求资源不被允许", Errors::REQUEST_RESOUTCE_NOT_ALLOWED);
        }
        
        if (!empty($params[2]))
        {
            $this->_requestFunction = $params[2];
        }
    }
}

3. 接口测试

3.1 项目准备

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 用户接口功能测试

3.2.1 建立user表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2 用户注册

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.3 用户登录

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.4 用户修改密码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.5 用户注销

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 便签接口功能测试

3.3.1 建立note表

在这里插入图片描述
在这里插入图片描述

3.3.2 添加便签

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.3 修改便签

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.4 删除便签

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.5 查询便签列表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.6 查询便签内容

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 生成在线接口文档

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 导出接口集合的JSON文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.6 导入接口集合的JSON文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 总结

  1. 首先了解一些SQL语句的写法以及PHP的语法,初学时不需要完全掌握,遇到问题时,善于使用搜索引擎;
  2. 配置开发环境,使用XAMPP集成环境,使用其中的Apache和MySQL,PHP项目编辑工具可以使用NetBeans,可视化数据库管理软件使用Navicat,接口测试工具使用Postman;
  3. 接口项目使用面向对象的思想实现,将不同资源的业务封装到对应的资源类进行管理,提取公用的函数放入工具类,将错误码集成到错误码类进行统一配置;
  4. 可以自行建立基本的文件夹和文件,也可以导入模板后进行修改,模板文件和项目文件下面的附录可见;
  5. 使用Postman对项目接口进行统一管理,便于相关功能的测试;
  6. 进行接口测试时,如果需要修改数据库中的数据,尽量通过相关的信息修改接口进行调整,不要直接在Navicat中进行修改,避免破坏数据表的数据完整性;

5. 附录

5.1 SQL学习链接

  1. 学习视频:https://www.bilibili.com/video/BV1Vt411z7wy
  2. 博客链接:https://blog.csdn.net/m0_50546016/article/details/120070003

5.2 PHP学习链接

  1. PHP菜鸟教程:https://www.runoob.com/php/php-tutorial.html
  2. 学习视频:https://www.bilibili.com/video/BV18x411H7qD

5.3 HTTP相关链接

  1. 相关博客:https://blog.csdn.net/weixin_45803426/article/details/116784443

5.4 项目模板链接

  1. 项目模板:https://gitee.com/icebear221/php-interface-development.git
  2. 项目模板:https://download.csdn.net/download/ice_bear221/85690606

5.5 完整项目链接

  1. 便签接口:https://gitee.com/icebear221/php-interface-development.git
  2. 便签接口:https://download.csdn.net/download/ice_bear221/85690547

5.6 接口开发学习链接

  1. 学习视频:https://www.bilibili.com/video/BV1kW411P7A9?p=8
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值