"thinkphp5开发restful-api接口" 教程视频 配套文档

视频配套文档, 为知笔记连接失效, 转至掘金 :)

视频教程地址:

thinkphp5开发restful-api接口javascript

正文


课程简介

主要内容php

  1. 基于thinkphp5框架, 为移动端APP开发数据接口
  2. php程序员最多见的工做

为app写后台 为app写接口html

什么是thinkphp5?java

  1. thinkphp5 是php框架thinkphp的最新的一个版本
  2. thinkphp官网
  3. thinkphp5手册
  4. thinkphp的优势

简单易用 功能齐全 利于扩展 方便学习 开发速度快 教程丰富python

什么是restful api?mysql

  • 一套api的设计规范

RESTful API 设计指南git

为何是这种搭配程序员

  • 兼顾api和后台

php: thinkphp5 + thinkcmf python: django + xadmingithub

本课程用到的工具sql

  1. php开发环境:phpstudy ==> windows + apache + mysql + php
  2. 编辑器:sublime
  3. 接口测试工具:postman
  4. 数据库工具:navicat for mysql

本课程的风格

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

本课程的学习基础

  1. 有php基础
  2. 熟悉mysql数据库

本课程的收获

  1. 学会了一门新的框架
  2. 学会如何为APP提供接口

第1节 经常使用工具介绍

sublime(最性感的编辑器)

  • 最性感的编辑器

启动速度快(C++) 插件众多(python)

下载sublime

安装版和绿色便携版的区别

  1. 安装板支持右键菜单, 可是不方便迁移
  2. 绿色便携版方便迁移, 可是不支持右键菜单
  3. 推荐绿色便携版, 右键菜单解决方案(sublime_addright.inf)
[Version]
Signature="$Windows NT$"

[DefaultInstall]
AddReg=SublimeText3

[SublimeText3]
hkcr,"*\\shell\\SublimeText3",,,"用 SublimeText3 打开"
hkcr,"*\\shell\\SublimeText3\\command",,,"""%1%\sublime_text.exe"" ""%%1"" %%*"
hkcr,"Directory\shell\SublimeText3",,,"用 SublimeText3 打开"
hkcr,"*\\shell\\SublimeText3","Icon",0x20000,"%1%\sublime_text.exe, 0"
hkcr,"Directory\shell\SublimeText3\command",,,"""%1%\sublime_text.exe"" ""%%1"""
复制代码

激活sublime

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

sublime经常使用配置

{
    "font_face": "YaHei Consolas Hybrid", // 字体名称
    "font_size": 13, // 字体大小
    "save_on_focus_lost": true, // 自动保存
    "word_wrap": true, // 开启自动换行
}
复制代码

sublime安装插件

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

postman(接口测试)

  1. postman的前世此生
  2. 官方文档 (全英文, 图文并茂)
  3. 测试接口

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

  1. 经常使用设置

选择 http 方法 自动生成代码 接口鉴权 设置接受数据的方式 设置字体大小 保存接口以备后用 post 参数的两种方式

navicat(数据库管理)

  1. 下载与安装
  2. 新建mysql链接
  3. 新建数据库
  4. 新建数据表(图形化界面/自动完成)
  5. 查看表结构
  6. 原生sql查询
  7. 导入/导出数据库

phpstudy(php开发环境)

  1. 为何选择phpstudy

一次性安装,无须配置便可使用 完美支持win10, 支持自定义php版本

  1. 启动/中止/重启

运行环境(选择 非系统模式 就能够了) 支持右键分开启停 切换版本(切记: NTS版本的PHP,APACHE不支持REWRITE! )

  1. 快速跳转配置文件

php-ini php配置文件(自动识别版本 http-conf apache配置文 mysql-ini mysql配置文 vhosts-conf apache虚拟主机配置文

  1. 快速跳转软件位置

hosts 网站根目录

  1. 查看phpinfo

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

  1. php扩展及设置

php扩展 (等于直接操做 php.ini ) 参数开关设置 (等于直接操做 php.ini ) 参数值设置 (等于直接操做 php.ini )

  1. 操做mysql

快速打开命令行 快速新建数据库 设置mysql (等于直接操做 mysql.ini ) MYSQL工具 =====> 参数值设置

  1. 为apache增长模块 (等于直接操做 httpd.conf )

第2节 以豆瓣网为例, 讲解restful api设计规范

什么是restful api

  • 目前比较成熟的一套互联网应用程序的API设计理论

豆瓣电影api

  1. 应该尽可能将API部署在专用域名之下

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

  1. 应该将API的版本号放入URL

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

  1. 在RESTful架构中,每一个网址表明一种资源(resource),因此网址中不能有动词,只能有名词,并且所用的名词每每与数据库的表格名对应。通常来讲,数据库中的表都是同种记录的"集合"(collection),因此API中的名词也应该使用复数。

api.douban.com/v2/book/:id (获取图书信息) api.douban.com/v2/movie/subject/:id (电影条目信息) api.douban.com/v2/music/:id (获取音乐信息) api.douban.com/v2/event/:id (获取同城活动)

  1. 对于资源的具体操做类型,由HTTP动词表示。经常使用的HTTP动词有下面四个(对应增/删/改/查)。

GET(select):从服务器取出资源(一项或多项)。 eg. 获取图书信息 GET api.douban.com/v2/book/:id POST(create):在服务器新建一个资源。 eg. 用户收藏某本图书 POST api.douban.com/v2/book/:id… PUT(update):在服务器更新资源(客户端提供改变后的完整资源)。 eg. 用户修改对某本图书的收藏 PUT api.douban.com/v2/book/:id… DELETE(delete):从服务器删除资源。 eg. 用户删除某篇笔记 DELETE api.douban.com/v2/book/ann…

  1. 若是记录数量不少,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果

?limit=10:指定返回记录的数量 eg. 获取图书信息 GET api.douban.com/v2/book/:id?limit=10

  1. 服务器向用户返回的状态码和提示信息

每一个状态码表明不一样意思, 就像代号同样 2系 表明正常返回 4系 表明数据异常 5系 表明服务器异常

错误码 错误信息 含义 状态码
6000 book_not_found 图书不存在 404
6002 unauthorized_error 没有修改权限 403
6004 review_content_short(should more than 150) 书评内容太短(需多于150字) 400
6006 review_not_found 书评不存在 404
6007 not_book_request 不是豆瓣读书相关请求 403
6008 people_not_found 用户不存在 404
6009 function_error 服务器调用异常 400
6010 comment_too_long(should less than 350) 短评字数过长(需少于350字) 400
6011 collection_exist(try PUT if you want to update) 该图书已被收藏(如需更新请用PUT方法而不是POST) 409
6012 invalid_page_number(should be digit less than 1000000) 非法页码(页码须要是小于1000000的数字) 400
6013 chapter_too_long(should less than 100) 章节名过长(需小于100字) 400

接口安全

  1. API的身份认证应该使用OAuth 2.0框架。
  2. 技术团队本身约定的规则

增长两个参数 time, token time为时间戳, 用于判断接口请求是否超时 token为时间戳加密后的字符串, 加密规则只有大家技术团队本身知道


第3节 thinkphp5简易教程

什么是thinkphp

  1. 国人开发的php框架
  2. 源码中文注释, 方便理解
  3. 中文文档详尽
  4. 使用者多, 教程丰富

官网

安装

  1. 官网下载, 复制粘贴
  2. 检查环境
  3. 访问public文件夹

配置虚拟主机

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

URL路径设计

格式化php代码

  1. 安装phpfmt插件

ctrl+shift+p 搜索phpfmt enter

  1. 配置插件
{
    "format_on_save": true,
    "php_bin": "G:/phpStudy/php/php-7.0.12-nts/php.exe",
}
复制代码
  1. psr1和psr2区别

花括号点位置不一样

API友好

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

获取请求参数

<?php
namespace app\index\controller;
use \think\Request;
class Index {
    public function index() {
        $request = Request::instance();
        echo '请求方法:' . $request->method() . '<br/>';
        echo '访问地址:' . $request->ip() . '<br/>';
        echo '请求参数:';
        dump($request->param());
        echo '请求参数:仅包含name,sex';
        dump($request->only(['name', 'sex']));
        echo '请求参数:排除name,sex';
        dump($request->except(['name', 'sex']));
    }
}
复制代码

判断请求类型

// 是否为 GET 请求
if (Request::instance()->isGet()) echo "当前为 GET 请求";
// 是否为 POST 请求
if (Request::instance()->isPost()) echo "当前为 POST 请求";
// 是否为 PUT 请求
if (Request::instance()->isPut()) echo "当前为 PUT 请求";
// 是否为 DELETE 请求
if (Request::instance()->isDelete()) echo "当前为 DELETE 请求";
// 是否为 Patch 请求
if (Request::instance()->isPatch()) echo "当前为 PATCH 请求";
复制代码

验证参数数据

<?php
namespace app\index\controller;
use \think\Validate;
class Index {
    public function index() {
        $rule = [
            'name' => 'require|max:25',
            'age' => 'number|between:1,120',
            'email' => 'email',
        ];
        $msg = [
            'name.require' => '名称必须',
            'name.max' => '名称最多不能超过25个字符',
            'age.number' => '年龄必须是数字',
            'age.between' => '年龄只能在1-120之间',
            'email' => '邮箱格式错误',
        ];
        $data = input('post.');
        $validate = new Validate($rule, $msg);
        $result = $validate->check($data);
        if (!$validate->check($data)) {
            dump($validate->getError());
        }
    }
}
复制代码

链接数据库

/* 数据库设置 */
'database' => [
    // 数据库类型
    'type'        => 'mysql',
    // 服务器地址
    'hostname'    => '127.0.0.1',
    // 数据库名
    'database'    => 'thinkphp',
    // 数据库用户名
    'username'    => 'root',
    // 数据库密码
    'password'    => '',
    // 数据库链接端口
    'hostport'    => '',
    // 数据库链接参数
    'params'      => [],
    // 数据库编码默认采用utf8
    'charset'     => 'utf8',
    // 数据库表前缀
    'prefix'      => '',
    // 数据库调试模式
    'debug'       => false,
],
复制代码

原生sql语句查询

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

第4节 为api项目搭建数据库

什么是数据库三大范式

  1. 每一列都是不可分割的原子数据项
  2. 实体的属性彻底依赖于主关键字
  3. 任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

数据库中设计中的常见问题

  1. 字段混在了一块儿

  1. 数据表混在了一块儿

  1. 不会处理表关系

一对一 (学生姓名, 学号) 一对多 (老师, 学生) 多对多 (学生, 课程)

设计数据库的小技巧

  1. 一个对象, 一张表
  2. 一张表, 一个主键
  3. 表名中有数据库名作前缀
  4. 字段名中有表名作前缀
  5. 前缀后加缩写
  6. 数据表关系处理

范式越高越好?


第5节 使用markdown书写接口文档

基本语法

  1. 六级标题
  2. 目录索引
  3. 加粗
  4. 斜体
  5. 删除线
  6. 引用
  7. 代码段
  8. 表格
  9. 行内代码
  10. 无序列表
  11. 有序列表
  12. 图片
  13. 超连接

用户登陆举例

---
 # 第6节(判断数据库中是否有此用户)
 > `post` ~~www.test.com/api~~ `api.test.com`
 |参数|必选|类型|说明|
 |:-|:-:|:-:|:-|
 |*time*|*true*|*int*|*时间戳* (用于肯定接口的访问时间)|
 |*token*|*true*|*string*|*肯定访问者身份* (`MD5(USER_MD5(time)_USER)`)|
 |username |true |string|只接受`手机号`|
 |password |true |string |用户密码|
 ``` javascript
 {
 "ret": 200, // 返回结果状态。200:接口正常请求并返回/40*:服务端的数据有误/500:服务器运行错误
 "data": {
 "user_id": "27", // 用户id
 "user_tag": "1" // 用户身份
 },
 "msg": "" // 401:用户名不存在!/402:手机号不存在!/403:密码不正确!
 }
 ```
复制代码

第7节 为项目配置URL

需求分析

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

配置主域名和二级域名

  1. 打开phpstudy
  2. 其余选项菜单 ==> 站点域名管理

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

  1. 配置hosts(域名重定向)
127.0.0.1 www.tp5.com
127.0.0.1 api.tp5.com
复制代码

使用tp5路由进行URL解析

  1. 为sublime安装新插件(方便操做侧边栏)

package control: install package SideBarEnhancements

  1. 新建user.php文件

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

<?php
namespace app\api\controller;

class User{
    public function index($id){
        echo 'controller: user function: index';
        echo '<br/>';
        echo $id;
    }
}
复制代码
  1. 修改config.php(开启路由功能)

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

// 是否开启路由
'url_route_on' => true,
复制代码
  1. 配置路由规则

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

<?php
use think\Route;

// api.tp5.com ===> www.tp5.com/index.php/api
Route::domain('api','api');
// api.tp5.com/user/2 ===> www.tp5.com/index.php/api/user/index/id/2
Route::rule('user/:id','user/index');
复制代码

第8节 接口安全

常见的安全问题以及解决方案

  1. 接口被大规模调用消耗系统资源,影响系统的正常访问,甚至系统瘫痪

解决方案: 获取 timestamp (时间戳), 设置接口失效时间

  1. 接口数据被黑客篡改(伪造请求)

解决方案: 对参数加密, 生成 token , 判断 token 是否正确

  1. 数据被黑客截取

解决方案: 使用 https , 用证书对数据进行加密, 即便数据被截取, 对黑客也没有意义

黑客能够获取数据, 可是没法获取数据的加密方法

咱们api项目的安全设计

  1. time

时间戳, 用于判断请求是否超时, 设置为30秒

  1. token

其余参数加密而来, 保证数据不被篡改

  1. 敏感信息加密传输

接收加密过的用户密码, 用户密码永不返回 最好使用 https, 全部信息都会被加密

第9节 接口开发前的准备工做(参数过滤)

配置路由

  1. 开启路由功能

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

// 是否开启路由
'url_route_on' => true,
// 域名部署
'url_domain_deploy' => true,
复制代码
  1. 配置route.php

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

<?php
use think\Route;

// api.tp5.com ===> www.tp5.com/index.php/api
Route::domain('api','api');
// post api.tp5.com/user ---> user.php login()
Route::post('user','user/login');
复制代码

使用common.php统一处理参数过滤 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

<?php
namespace app\api\controller;
use think\Controller;
use think\Request;
use think\Validate;
class Common extends Controller {
    protected $request; // 用来处理参数
    protected $validater; // 用来验证数据/参数
    protected $params; // 过滤后符合要求的参数
    protected $rules = array(
            'User'=>array(......);
    protected function _initialize() {
        parent::_initialize();
        $this->request = Request::instance();
        $this->check_time($this->request->only(['time']));
        $this->check_token($this->request->param());
        $this->params = $this->check_params($this->request->except(['time','token']));
    }
复制代码

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

/** * api 数据返回 * @param [int] $code [结果码 200:正常/4**数据问题/5**服务器问题] * @param [string] $msg [接口要返回的提示信息] * @param [array] $data [接口要返回的数据] * @return [string] [最终的json数据] */
public function return_msg($code, $msg = '', $data = []) {
 
    /*********** 组合数据 ***********/
    $return_data['code'] = $code;
    $return_data['msg']  = $msg;
    $return_data['data'] = $data;
 
    /*********** 返回信息并终止脚本 ***********/
    echo json_encode($return_data);die;
}
复制代码

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

/** * 验证请求是否超时 * @param [array] $arr [包含时间戳的参数数组] * @return [json] [检测结果] */
public function check_time($arr) {
    if (!isset($arr['time']) || intval($arr['time']) <= 1) {
        $this->return_msg(400, '时间戳不正确!');
    }
    if (time() - intval($arr['time']) > 60) {
        $this->return_msg(400, '请求超时!');
    }
}
复制代码

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

/** * 验证token(防止篡改数据) * @param [array] $arr [所有请求参数] * @return [json] [token验证结果] */
public function check_token($arr) {
 
    /*********** api传过来的token ***********/
    if (!isset($arr['token']) || empty($arr['token'])) {
        $this->return_msg(400, 'token不能为空!');
    }
    $app_token = $arr['token']; // api传过来的token
 
    /*********** 服务器端生成token ***********/
    unset($arr['token']);
    $service_token = '';
    foreach ($arr as $key => $value) {
        $service_token .= md5($value);
    }
    $service_token = md5('api_' . $service_token . '_api'); // 服务器端即时生成的token
 
    /*********** 对比token,返回结果 ***********/
    if ($app_token !== $service_token) {
        $this->return_msg(400, 'token值不正确!');
    }
}
复制代码

为每一个接口配置验证规则 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

验证参数 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

/** * 验证参数 参数过滤 * @param [array] $arr [除time和token外的全部参数] * @return [return] [合格的参数数组] */
public function check_params($arr) {
 
    /*********** 获取参数的验证规则 ***********/
    $rule = $this->rules[$this->request->controller()][$this->request->action()];
 
    /*********** 验证参数并返回错误 ***********/
    $this->validater = new Validate($rule);
    if (!$this->validater->check($arr)) {
        $this->return_msg(400, $this->validater->getError());
    }
 
    /*********** 若是正常,经过验证 ***********/
    return $arr;
}
复制代码

第9节 获取验证码

接口文档 新建api_user表

DROP TABLE IF EXISTS `api_user`;
CREATE TABLE `api_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_phone` char(11) NOT NULL,
  `user_nickname` varchar(255) NOT NULL COMMENT '昵称',
  `user_email` varchar(255) NOT NULL,
  `user_rtime` int(11) NOT NULL COMMENT 'register time',
  `user_pwd` char(32) NOT NULL,
  `user_icon` varchar(255) NOT NULL COMMENT '用户头像',
  PRIMARY KEY (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
复制代码

验证码原理

  1. 生成及发送
  • 点击获取手机码
  • 发送手机号到后台
  • 后台生成手机码
  • 用session保存手机码及手机号
  • 用短信发送平台的接口发送出去
  1. 验证
  • 获取用户输入的手机码及手机号
  • 取出session保存的内容
  • 对比验证
  • 返回信息, 结束

配置路由

注意: get方式没有参数名, 因此要注意参数的顺序, 对号入座.

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

// 获取验证码
Route::get('code/:time/:token/:username/:is_exist','code/get_code');
复制代码

参数过滤

在common.php里简单过滤, 具体验证放在code.php里

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

'Code' => array(
    'get_code' => array(
        'username' => 'require',
        'is_exist' => 'require|number|length:1',
    ),
),
复制代码

检测用户名 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

namespace app\api\controller;
use phpmailer\phpmailer;
use submail\messagexsend;
 
class Code extends Common {
    public function get_code() {
        $username      = $this->params['username'];
        $exist         = $this->params['is_exist'];
        $username_type = $this->check_username($username); // 检查用户名, 决定用下面哪那个函数
        switch ($username_type) {
        case 'phone':
            $this->get_code_by_username($username, 'phone', $exist); // 经过手机获取验证码
            break;
        case 'email':
            $this->get_code_by_username($username, 'email', $exist); // 经过邮箱获取验证码
            break;
        }
    }
}
复制代码

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

public function check_username($username) {
    /*********** 判断是否为邮箱 ***********/
    $is_email = Validate::is($username, 'email') ? 1 : 0;
    /*********** 判断是否为手机 ***********/
    $is_phone = preg_match('/^1[34578]\d{9}$/', $username) ? 4 : 2;
    /*********** 最终结果 ***********/
    $flag = $is_email + $is_phone;
    switch ($flag) {
    /*********** not phone not email ***********/
    case 2:
        $this->return_msg(400, '邮箱或手机号不正确!');
        break;
    /*********** is email not phone ***********/
    case 3:
        return 'email';
        break;
    /*********** is phone not email ***********/
    case 4:
        return 'phone';
        break;
    }
}
复制代码

经过用户名(手机/邮箱)获取验证码 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

public function get_code_by_username($username, $type, $exist) {
    if ($type == 'phone') {
        $type_name = '手机';
    } else {
        $type_name = '邮箱';
    }
    /*********** 检测手机号/邮箱是否存在 ***********/
    $this->check_exist($username, $type, $exist);
    /*********** 检查验证码请求频率 30秒一次 ***********/
    if (session("?" . $username . '_last_send_time')) {
        if (time() - session($username . '_last_send_time') < 30) {
            $this->return_msg(400, $type_name . '验证码,每30秒只能发送一次!');
        }
    }
    /*********** 生成验证码 ***********/
    $code = $this->make_code(6);
    /*********** 使用session存储验证码, 方便比对, md5加密 ***********/
    $md5_code = md5($username . '_' . md5($code));
    session($username . '_code', $md5_code);
    /*********** 使用session存储验证码的发送时间 ***********/
    session($username . '_last_send_time', time());
    /*********** 发送验证码 ***********/
    if ($type == 'phone') {
        $this->send_code_to_phone($username, $code);
    } else {
        $this->send_code_to_email($username, $code);
    }
}
复制代码

判断用户名(手机/邮箱)是否应该存在 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

生成验证码 G:\phpStudy\WWW\tp5\application\api\controller\Code.php

public function make_code($num) {
    $max = pow(10, $num) - 1;
    $min = pow(10, $num - 1);
    return rand($min, $max);
}
复制代码

经过邮箱发送验证码

去邮箱开启smtp php须要开启php_openssl 如今phpmailer并把须要的文件添加进thinkphp5

  • G:\phpStudy\WWW\tp5\extend\phpmailer\phpmailer.php
namespace phpmailer;
use phpmailer\smtp;
class PHPMailer ...... class phpmailerException extends \Exception...... // 须要加\ 复制代码
  • G:\phpStudy\WWW\tp5\extend\phpmailer\smtp.php
namespace phpmailer;
class SMTP ...... 复制代码

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

public function send_code_to_email($email, $code) {
    $toemail = $email;
    $mail    = new PHPMailer();
    $mail->isSMTP();
    $mail->CharSet    = 'utf8'; // 设置字符集
    $mail->Host       = 'smtp.126.com'; // smtp服务器
    $mail->SMTPAuth   = true;
    $mail->Username   = "xujunhao_api@126.com";
    $mail->Password   = "xujunhao890518"; // 本身设置的smtp密码, 与登陆密码无关
    $mail->SMTPSecure = 'ssl';
    $mail->Port       = 994;
    $mail->setFrom('xujunhao_api@126.com', '接口测试');
    $mail->addAddress($toemail, 'test');
    $mail->addReplyTo('xujunhao_api@126.com', 'Reply');
    $mail->Subject = "您有新的验证码!"; // 邮件标题
    $mail->Body    = "这是一个测试邮件,您的验证码是$code,验证码的有效期为1分钟,本邮件请勿回复!"; // 邮件内容
    if (!$mail->send()) {
        $this->return_msg(400, $mail->ErrorInfo);
    } else {
        $this->return_msg(200, '验证码已经发送成功,请注意查收!');
    }
}
复制代码

经过手机发送验证码 使用submail(赛迪云通讯)

  1. 经过调用接口发送短信
  • 开启php_curl
  • 安装本地证书下载证书
  • G:\phpStudy\php\php-5.5.38\php.ini
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "G:\phpStudy\php\php-5.5.38\cacert.pem"
复制代码
  • G:\phpStudy\WWW\tp5\application\api\controller\Code.php
public function send_code_to_phone($phone, $code) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://api.mysubmail.com/message/xsend');
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    $data = [
        'appid'   => '15180',
        'to'      => $phone,
        'project' => '9CTTG2',
        'vars'    => '{"code":' . $code . ',"time":"60"}',
        'signature'=>'76a9e82484c83345b7850395ceb818fb',
    ];
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    $res = curl_exec($curl);
    curl_close($curl);
    $res = json_decode($res);
    if ($res->status != 'success') {
        $this->return_msg(400,$res->msg);
    }else{
        $this->return_msg(200,'手机验证码已发送, 天天发送5次, 请在一分钟内验证!');
    }
    dump($res->staus);die;
}
复制代码
  1. 使用sdk发送验证码
  • 下载sdk, 把须要的文件加入thinkphp5
  • G:\phpStudy\WWW\tp5\extend\submail\message.php
namespace submail;
class message {......
复制代码
  • G:\phpStudy\WWW\tp5\extend\submail\messagexsend.php
namespace submail;
use submail\message;
class MESSAGEXsend {

    protected $appid = '';

    protected $appkey = '';

    protected $sign_type = '';

    protected $To = array();

    protected $Addressbook = array();

    protected $Project = '';

    protected $Vars = array();

    function __construct() {
        $this->appid  = "15180";
        $this->appkey = "76a9e82484c83345b7850395ceb818fb";
        $this->sign_type = 'normal';
    }
复制代码
  • G:\phpStudy\WWW\tp5\application\api\controller\Code.php
public function send_code_to_phone($phone, $code) {
    $submail = new MESSAGEXsend();
    $submail->SetTo($phone);
    $submail->SetProject('9CTTG2');
    $submail->AddVar('code', $code);
    $submail->AddVar('time', 60);
    $xsend = $submail->xsend();
    if ($xsend['status'] !== 'success') {
        $this->return_msg(400, $xsend['msg']);
    } else {
        $this->return_msg(200, '手机验证码已发送, 天天发送5次, 请在一分钟内验证!');
    }
}
复制代码

第10节 用户注册

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

// 用户注册
Route::post('user/register','user/register');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

关闭数据库字段检查 G:\phpStudy\WWW\tp5\application\database.php

// 是否严格检查字段是否存在
'fields_strict'   => false,
复制代码

书写register函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function register() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检查验证码 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 检测用户名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 0);
        $data['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 0);
        $data['user_email'] = $data['user_name'];
        break;
    }
    /*********** 将用户信息写入数据库 ***********/
    unset($data['user_name']);
    $data['user_rtime'] = time(); // register time
    $res                = db('user')->insert($data);
    if (!$res) {
        $this->retrun_msg(400, '用户注册失败!');
    } else {
        $this->return_msg(200, '用户注册成功!');
    }
}
复制代码

检查验证码 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

public function check_code($user_name, $code) {
    /*********** 检测是否超时 ***********/
    $last_time = session($user_name . '_last_send_time');
    if (time() - $last_time > 60) {
        $this->return_msg(400, '验证超时,请在一分钟内验证!');
    }
    /*********** 检测验证码是否正确 ***********/
    $md5_code = md5($user_name . '_' . md5($code));
    if (session($user_name . "_code") !== $md5_code) {
        $this->return_msg(400, '验证码不正确!');
    }
    /*********** 无论正确与否,每一个验证码只验证一次 ***********/
    session($user_name . '_code', null);
}
复制代码

第11节 用户登陆

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

// 用户登陆
Route::post('user/login','user/login');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'login'    => array(
            'user_name' => 'require',
            'user_pwd'  => 'require|length:32',
        ),
    ),
);
复制代码

书写login函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function login() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检测用户名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $db_res = db('user')
            ->field('user_id,user_name,user_phone,user_email,user_rtime,user_pwd')
            ->where('user_phone', $data['user_name'])
            ->find();
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $db_res = db('user')
            ->field('user_id,user_name,user_phone,user_email,user_rtime,user_pwd')
            ->where('user_email', $data['user_name'])
            ->find();
        break;
    }
    if ($db_res['user_pwd'] !== $data['user_pwd']) {
        $this->return_msg(400, '用户名或者密码不正确!');
    } else {
        unset($db_res['user_pwd']); // 密码永不返回
        $this->return_msg(200, '登陆成功!', $db_res);
    }
}
复制代码

第12节 用户上传头像

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

// 用户上传你头像
Route::post('user/icon','user/upload_head_img');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

修改参数过滤 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

$this->params = $this->check_params($this->request->param(true));
复制代码

编写upload_head_img函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function upload_head_img() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 上传文件,得到路径 ***********/
    $head_img_path = $this->upload_file($data['user_icon'], 'head_img');
    /*********** 存入数据库 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_icon', $head_img_path);
    if ($res) {
        $this->return_msg(200, '头像上传成功!', $head_img_path);
    } else {
        $this->return_msg(400, '上传头像失败!');
    }
}
复制代码

编写upload_file函数 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

编写image_edit函数 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

第13节 用户修改密码

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

// 用户修改密码
Route::post('user/change_pwd','user/change_pwd');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

protected $rules = array(
    'User' => array(
        'change_pwd'      => array(
            'user_name'    => 'require',
            'user_ini_pwd' => 'require|length:32',
            'user_pwd'     => 'require|length:32',
        ),
    ),
);
复制代码

编写change_pwd函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function change_pwd() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检查用户名并取出数据库中的密码 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $where['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $where['user_email'] = $data['user_name'];
        break;
    }
    /*********** 判断原始密码是否正确 ***********/
    $db_ini_pwd = db('user')->where($where)->value('user_pwd');
    if ($db_ini_pwd !== $data['user_ini_pwd']) {
        $this->return_msg(400, '原密码错误!');
    }
    /*********** 把新的密码存入数据库 ***********/
    $res = db('user')->where($where)->setField('user_pwd', $data['user_pwd']);
    if ($res !== false) {
        $this->return_msg(200, '密码修改为功!');
    } else {
        $this->return_msg(400, '密码修改失败!');
    }
}
复制代码

第14节 找回密码

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

// 用户找回密码
Route::post('user/find_pwd','user/find_pwd');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

书写find_pwd函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function find_pwd() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检测验证码 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 检测用户名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $this->check_exist($data['user_name'], 'phone', 1);
        $where['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $this->check_exist($data['user_name'], 'email', 1);
        $where['user_email'] = $data['user_name'];
        break;
    }
    /*********** 修改数据库 ***********/
    $res = db('user')->where($where)->setField('user_pwd', $data['user_pwd']);
    if ($res !== false) {
        $this->return_msg(200, '密码修改为功!');
    } else {
        $this->return_msg(400, '密码修改失败!');
    }
}
复制代码

第15节 用户手机号/邮箱绑定

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

// 用户绑定手机号
Route::post('user/bind_phone','user/bind_phone');
// 用户绑定邮箱
Route::post('user/bind_email','user/bind_email');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

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

书写bind_phone函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function bind_phone() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检查验证码 ***********/
    $this->check_code($data['phone'], $data['code']);
    /*********** 修改数据库 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_phone', $data['phone']);
    if ($res !== false) {
        $this->return_msg(200, '手机号绑定成功!');
    } else {
        $this->return_msg(400, '手机号绑定失败!');
    }
}
复制代码

书写bind_email函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function bind_email() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检查验证码 ***********/
    $this->check_code($data['email'], $data['code']);
    /*********** 修改数据库 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->setField('user_email', $data['email']);
    if ($res !== false) {
        $this->return_msg(200, '邮箱绑定成功!');
    } else {
        $this->return_msg(400, '邮箱绑定失败!');
    }
}
复制代码

两个接口合成一个

  1. 配置路由

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

// 用户绑定邮箱/手机
Route::post('user/bind_username','user/bind_username');
复制代码
  1. 验证数据

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

'bind_username'        => array(
    'user_id' => 'require|number',
    'user_name'  => 'require',
    'code'      => 'require|number|length:6',
),
复制代码
  1. 书写bind_username函数

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

public function bind_username() {
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检测验证码 ***********/
    $this->check_code($data['user_name'], $data['code']);
    /*********** 判断用户名 ***********/
    $user_name_type = $this->check_username($data['user_name']);
    switch ($user_name_type) {
    case 'phone':
        $type_text                 = '手机号';
        $update_data['user_phone'] = $data['user_name'];
        break;
    case 'email':
        $type_text                 = '邮箱';
        $update_data['user_email'] = $data['user_name'];
        break;
    }
    /*********** 修改数据库 ***********/
    $res = db('user')->where('user_id', $data['user_id'])->update($update_data);
    if ($res !== false) {
        $this->return_msg(200, $type_text . '绑定成功!');
    } else {
        $this->return_msg(400, $type_text . '绑定失败!');
    }
}
复制代码

第16节 用户修改昵称

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

// 用户修改昵称
Route::post('user/nickname','user/set_nickname');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'set_nickname'        => array(
    'user_id' => 'require|number',
    'user_nickname'  => 'require|chsDash',
),
复制代码

编写set_nickname函数 G:\phpStudy\WWW\tp5\application\api\controller\User.php

public function set_nickname(){
    /*********** 接收参数 ***********/
    $data = $this->params;
    /*********** 检测昵称 ***********/
    $res = db('user')->where('user_nickname',$data['user_nickname'])->find();
    if ($res) {
        $this->return_msg(400,'该昵称已被占用!');
    }
    /*********** 写入数据库 ***********/
    $res = db('user')->where('user_id',$data['user_id'])->setField('user_nickname',$data['user_nickname']);
    if (!$res) {
        $this->return_msg(400,'修改昵称失败!');
    }else{
        $this->return_msg(200,'昵称修改为功!');
    }
}
复制代码

第17节 新增文章

接口文档 新建api_article表

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

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

// 新增文章
Route::post('article','article/add_article');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'add_article' => array(
        'article_uid' => 'require|number',
        'article_title' => 'require|chsDash',
    ),
),
复制代码

编写add_article函数 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function add_article() {
        /*********** 接收参数 ***********/
        $data                  = $this->params;
        $data['article_ctime'] = time();
        /*********** 写入数据库 ***********/
        $res = db('article')->insertGetId($data);
        if ($res) {
            $this->return_msg(200, '新增文章成功!',$res);
        } else {
            $this->return_msg(400, '新增文章失败!');
        }
    }
}
复制代码

参数安全html代码实体化

防止跨域脚本攻击

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

// 默认全局过滤方法 用逗号分隔多个
'default_filter'         => 'htmlspecialchars',
复制代码

第18节 查看文章列表

接口文档

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

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

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'article_list' => array(
        'user_id' => 'require|number',
        'num' => 'number',
        'page' => 'number',
    ),
),
复制代码

编写article_list函数 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function article_list() {
        /*********** 接收参数 ***********/
        $data = $this->params;
        if (!isset($data['num'])) {
            $data['num'] = 10;
        }
        if (!isset($data['page'])) {
            $data['page'] = 1;
        }
        /*********** 查询数据库 ***********/
        $where['article_uid'] = $data['user_id'];
        $where['article_isdel'] = 0;
        $count                = db('article')->where($where)->count();
        $page_num             = ceil($count / $data['num']);
        $field                = "article_id,article_ctime,article_title,user_nickname";
        $join                 = [['api_user u', 'u.user_id = a.article_uid']];
        $res                  = db('article')->alias('a')->field($field)->join($join)->where($where)->page($data['page'], $data['num'])->select();
        /*********** 判断并输出 ***********/
        if ($res === false) {
            $this->return_msg(400, '查询失败!');
        } elseif (empty($res)) {
            $this->return_msg(200, '暂无数据!');
        } else {
            $return_data['articles'] = $res;
            $return_data['page_num'] = $page_num;
            $this->return_msg(200, '查询成功!', $return_data);
        }
    }
}
复制代码

第19节 查看单个文章

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

// 获取单个文章信息
Route::get('article/:time/:token/:article_id','article/article_detail');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'article_detail' => array(
        'article_id' => 'require|number',
    ),
),
复制代码

编写article_detail函数 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function article_detail() {
        /*********** 接收参数 ***********/
        $data = $this->params;
        /*********** 查询数据库 ***********/
        $field                  = 'article_id,article_title,article_ctime,article_content,user_nickname';
        $where['article_id']    = $data['article_id'];
        $join                   = [['api_user u', 'u.user_id = a.article_uid']];
        $res                    = db('article')->alias('a')->join($join)->field($field)->where($where)->find();
        $res['article_content'] = htmlspecialchars_decode($res['article_content']);
        /*********** 判断结果并输出 ***********/
        if (!$res) {
            $this->return_msg(400, '查询失败!');
        } else {
            $this->return_msg(200, '查询成功!', $res);
        }
    }
}
复制代码

第20节 修改文章

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

// 修改/更新文章
Route::put('article','article/update_article');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'update_article' => array(
        'article_id' => 'require|number',
        'article_title'=>'chsDash'
    ),
),
复制代码

编写update_article函数 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function update_article() {
        /*********** 接收参数 ***********/
        $data = $this->params;
        /*********** 存入数据库 ***********/
        $res = db('article')->where('article_id', $data['article_id'])->update($data);
        if ($res !== false) {
            $this->return_msg(200, '修改文章成功!');
        } else {
            $this->return_msg(400, '修改文章失败!');
        }
    }
}
复制代码

第21节 删除文章

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

// 删除文章
Route::delete('article/:time/:token/:article_id','article/del_article');
复制代码

验证数据 G:\phpStudy\WWW\tp5\application\api\controller\Common.php

'Article' => array(
    'del_article' => array(
        'article_id' => 'require|number',
    ),
),
复制代码

为逻辑删除增长字段article_isdel

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

编写del_article函数 G:\phpStudy\WWW\tp5\application\api\controller\Article.php

<?php
namespace app\api\controller;
class Article extends Common {
    public function del_article(){
        /*********** 接收参数 ***********/
        $data = $this->params;
        /*********** 删除数据(逻辑删除) ***********/
        $res = db('article')->where('article_id',$data['article_id'])->setField('article_isdel',1);
        /*********** 删除数据(物理删除) ***********/
        // $res = db('article')->delete($data['article_id']);
        if ($res) {
            $this->return_msg(200,'删除文章成功');
        }else{
            $this->return_msg(400,'删除文章失败!');
        }
    }
}
复制代码
相关文章
相关标签/搜索