文章目录
基础知识
thinkphp5简易教程
获取请求参数
<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:';
dump($request->except(['name']));
}
}
结果:
判断请求类型
namespace app\index\controller;
use \think\Request;
class Index {
public function index() {
$request = Request::instance();
if($request->isGet())
echo '是get方法!';
if($request->isPost())
echo '是post方法!';
if($request->isPatch())
echo '是patch方法!';
if($request->isDelete())
echo '是delete方法!';
if($request->isPut())
echo '是put方法!';
}
}
验证参数数据
<?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(!result) {
dump($validate->getError());
}
}
}
为api项目搭建数据库
设计数据库的小技巧
- 一个对象,一张表
- 一张表,一个主键
- 表名中由数据库名做前提
- 字段名中由表名做前提
- 前缀后加缩写
数据库中合理性vs性能
接口文档实例
用户登陆(判断数据库中是否有此用户)
post
www.test.com/apiapi.test.com
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
time | true | int | 时间戳(用于确定接口的访问时间) |
token | true | string | 确定访问者身份(MD5(USER_MD5(time)_USER) ) |
username | true | string | 只接受手机号 |
password | true | string | 用户密码 |
{
"ret":200,//返回结果状态。200:接口正常请求并返回/40*:服务端的数据有误/500:服务器运行错误
"data";{
"user_id":"27",//用户id
"user_tag"://用户身份
},
"msg":""//401:用户名不存在!/402:手机号不存在!/403:密码不正确
}
接口开发前的准备工作
Common.php
<?php
namespace app\api\controller;
use think\Controller;
use think\Request;
use think\Validate;
use think\Db;
use think\Image;
class Common extends Controller {
protected $request;
protected $params;
protected $validate;
protected $rules = arry(
'Code' => array(
'get_code' => array(
'username' => 'require',
'is_exist' => 'require|number|length:1'
)
),
'User' => array(
'register' => array(
'user_name' => 'require',
'user_pwd' => 'require|length:32',
'code' => 'require|number|length:6'
),
'login' => array(
'user_name' => 'require',
'user_pwd' => 'require|length:32'
),
'upload_icon' => array(
'user_id' => 'require|number',
'user_icon' => 'require|fileSize:2000000|fileExt:jpg,png,svg'
),
'change_pwd' => array(
'user_name' => 'require',
'user_ini_pwd' => 'require|length:32',
'user_pwd' => 'require|length:32'
),
'find_pwd' => array(
'user_name' => 'require',
'code' => 'require|number|length:6',
'user_pwd' => 'require|length:6'
),
'bind_phone' => array(
'user_id' => 'require|number',
'code' => 'require|number|length:6',
'phone' => ['require','regex'=>'/^1[34578]\d{9}$/']
),
'bind_email' => array(
'user_id' => 'require|number',
'code' => 'require|number|length:6',
'email' => 'require|email'
),
'set_nickname' => array(
'user_id' => 'require|number',
'user_nickname' => 'require|chsDash'
)
),
'Article' => array(
'add_article' => array(
'article_uid' => 'require|number',
'article_title' => 'require|chaDash'
),
'article_list' => array(
'user_id' => 'require|number',
'num' => 'number',
'page' => 'number'
),
'article_detail' => array(
'article_id' => 'require|number'
),
'update_article' => array(
'article_id' => 'require|number'
),
'del_article' => array(
'article_id' => 'require|number'
)
)
)
public function _initialize() {
parent::_initialize();
$request = Request::instance();
//检测时间戳
$this->check_time($this->request->only(['time']));
//检测token值
$this->check_token($this->request->params());
//检测参数是否符合要求
$this->check_parma($this->request->params(true));
}
public function check_time($arr) {
//判断时间是否存在
if(!isset($arr['time']) || intval($arr['time'])) {
$this->return_msg(400,'时间不能为空!');
}
//判断是否超时
if(time() - intval($arr['time']) > 60) {
$this->return_msg(400,'请求超时!');
}
}
public function return_msg($code,$message,$data) {
$return_data['code'] = $code;
$return_data['message'] = $message;
$return_data['data'] = $data;
echo json_encode($return_data);
}
public function check_token($arr) {
//判断token是否存在
if(!isset($arr['token']) || empty($arr['token'])) {
$this->return_msg(400,'token值不能为空!');
}
//获取api传来的token值
$api_token = $arr['token'];
//去除token值
unset($arr['token']);
//生成server端的token值
$server_token = '';
foreach($arr as $key=>$value) {
$server_token .= md5($value);
}
//比较两个token值并输出结果
if($api_token !== $server_token) {
$this->return_msg(400,'参数错误!');
}
}
public function check_params($arr) {
$rule = $this->rules[$this->request->controller()][$this->request->action()];
$this->validate = new Validate($rule);
if(!$this->validate->check($arr)) {
$this->return_msg(400,$this->validate->getError());
}
return $arr;
}
//判断用户名类型
public function check_username($username) {
$phone_res = preg_match("/^1[34578]\d{9}$/",$username) ? 0 : 1;
$email_res = Validate::is($username,'email') ? 2 : 4;
$flag = $phone_res + $email_res;
switch($flag) {
//is phone not email
case 4 :
return 'phone';
break;
//is email not phone
case 3 :
return 'email';
break;
//not phone not email
case 5 :
$this->return_msg(400,'手机号或邮箱错误!');
}
}
public function check_exist($username,$type,$exist) {
if($type == 'phone') {
$db_res = db('user')->where('user_phone',$username)->find();
if($exist && !$db_res)
$this->return_msg(400,'此手机号不存在!');
if(!$exist && $db_res)
$this->return_msg(400,'此手机号已被占用!');
}
if($type == 'email') {
$db_res = db('user')->where('user_email',$username)->find();
if($exist && !$db_res)
$this->return_msg(400,'此邮箱不存在!');
if(!$exist && $db_res)
$this->return_msg(400,'此邮箱已被占用!');
}
}
public function check_code($username,$code) {
//检测验证码是否超时
if(time() - session($username.'_last_send_code_time') > 60) {
//验证码只能验证一次
session($username.'_code',null);
$this->return_msg(400,'验证码超时,请重新验证!');
}
//检测验证码
$md5_code = md5($code);
if(session($username.'_code') !== $md5_code) {
//验证码只能验证一次
session($username.'_code',null);
$this->return_msg(400,'验证码错误!');
}
}
public function achieve_path($user_icon,$type) {
//DS 当前系统的目录分隔符
$info = $user_icon->move(ROOT_PATH.'public'.DS.'uploads');
if($info) {
$path = '/uploads/'.$info->getSaveName();
if(!empty($type)) {
switch($type) {
case 'head_img':
$image = Image::open(ROOT_PATH.'public'.$path);
$image->thumb(200,200,Image::THUMB_CENTER)->save(ROOT_PATH.'public',$path);
break;
}
}
} else {
$this->return_msg(400,$user_icon->getError());
}
}
}
User.php
<?php
namespace app\api\controller;
class User extends Common {
public function login() {
$data = $this->params;
dump($data);
}
}
用户接口
验证码接口
Code.php
<?php
namespace app\api\controller;
use phpmailer\phpmailer;
use submail\messagexsend;
class Code extends Common() {
public function get_code() {
//接受参数
$data = $this->params;
//判断用户名类型
$username_type = $this->check_username($data['username']);
//判断用户名是否存在
$this->check_exist($data['username'],$username_type,$data['is_exist']);
//检测请求时间是否频繁
if("?".session($data['username'].'_last_send_code_time')) {
if(time() - session($data['username'].'_last_send_code_time') < 30) {
$this->return_msg(400,'请求频繁,稍后再试!');
}
}
//生成验证码并保存(ctime,code)
$code = rand(pow(10,5),pow(10,6)-1);
$md5_code = md5($code);
session($data['username'].'_code',$md5_code);
session($data['username'].'_last_send_code_time',time());
//根据用户名类型发送验证码
switch(username_type) {
case 'phone':
$this->send_code_to_phone($data['username'],$code);
break;
case 'email':
$this->send_code_to_email($data['username'],$code);
break;
}
}
public function send_code_to_phone($username,$code) {
$submail = new MESSAGEXsend();
$submail->SetTo($username);
$submail->SetProject('9CTTG2');
$submail->AddVar('code',$code);
$submail->AddVar('time',60);
$xsend = $submail->xsend();
if($xsend['status'] == 'success') {
$this->return_msg(200,'手机验证码已发送,请注意查收!');
} else {
$this->return_msg(400,$xsend['msg']);
}
}
public function send_code_to_email($username,$code) {
$mail = new PHPMailer();
$msil->isSMTP();
$mail->CharSet = 'utf8';
$mail->Host = 'smtp.126.com';
$mail->SMTPAuth = true;
$mail->Username = 'yangzichao_api@126.com';
$mail->Password = 'yangzichao1753';
$mail->SMTPSecure = 'ssl';
$mail->Port = 994;
$mail->setFrom('yangzichao_api@126.com','yzc');
$mail->addAddress($username,'lyr');
$mail->addReplyTo('yangzichao_api@126.com','Reply');
$mail->Subject = '您有新的验证码!';
$mail->Body = "您的验证码为$code,验证时间一分钟";
if($mail->send()) {
$this->return_msg(200,'邮箱验证码已成功发送,请注意查收!');
} else {
$this->return_msg(400,$mail->ErrorInfo);
}
}
}
用户注册接口
User.php中的register方法
//用户注册
public function register() {
//接受参数
$data = $this->params;
//检测验证码
$this->check_code($data['user_name'],$data['code']);
//检测用户名
$username_type = $this->check_username($data['user_name']);
switch($username_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();
$db_res = db('user')->insert($data);
//判断并输出结果
if($db_res) {
$this->return_msg(200,'注册成功!');
} else {
$this->return_msg(400,'注册失败!');
}
}
用户登陆接口
User.php中的login方法
//用户登录
public function login() {
//接受参数
$data = $this->params;
//检测用户名
$username_type = $this->check_username($data['user_name']);
$this->check_exist($data['user_name'],$username_type,1);
//数据库查询
if($username_type == 'phone') {
$db_res = db('user')
->field('user_id,user_phone,user_rtime,user_pwd,user_email')
->where('user_phone',$data['user_name'])
->find();
} else if($username_type == 'email') {
$db_res = db('user')
->field('user_id,user_phone,user_rtime,user_pwd,user_email')
->where('user_email',$data['user_name'])
->find();
}
//判断并输出结果
if($data['user_pwd'] !== $db_res['user_pwd']) {
$this->return_msg(400,'验证码或密码错误!');
} else {
unset($db_res['user_pwd']);
$this->return_msg(200,'登录成功!');
}
}
用户上传头像接口
User.php中的upload_head_img方法
public function upload_icon() {
//接受参数
$data = $this->params;
//获取图片路径并剪切
$path = $this->achieve_path($data['user_icon'],'head_img');
//存入数据库
$db_res = db('user')->where('user_id',$data['user_id'])->setField('user_icon',$path);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'上传头像成功!',$path);
} else {
$this->return_msg(400,'上传头像失败!');
}
}
用户修改密码接口
User.php中的change_pwd()方法
public function change_pwd() {
//接受参数
$data = $this->params;
//判断用户名
$username_type = $this->check_username($data['user_name']);
$this->check_exist($data['user_name'],$username_type,1);
//比较密码并修改原密码
if($username_type === 'phone') {
$user_ini_pwd = db('user')->where('user_phone',$data['user_name'])->vlaue('user_pwd');
if($data['user_ini_pwd'] === $user_ini_pwd) {
$db_res = db('user')->where('user_phone',data['user_name'])->setField('user_pwd',$data['user_pwd']);
if($db_res !== false) {
$this->return_msg(200,'密码修改成功!');
} else {
$this->return_msg(400,'密码修改失败!');
}
} else {
$this->return_msg(400,'原密码错误');
}
} else if($usernmae_type === 'email') {
$user_ini_pwd = db('user')->where('user_email',$data['user_name'])->vlaue('user_pwd');
if($data['user_ini_pwd'] === $user_ini_pwd) {
$db_res = db('user')->where('user_email',data['user_name'])->setField('user_pwd',$data['user_pwd']);
if($db_res !== false) {
$this->return_msg(200,'密码修改成功!');
} else {
$this->return_msg(400,'密码修改失败!');
}
} else {
$this->return_msg(400,'原密码错误');
}
}
}
用户找回密码接口
User.php中的find_pwd()方法
public function find_pwd() {
//接受参数
$data = $this->params;
//检测验证码
$this->check_code($data['user_name'],$data['code']);
//判断用户名
$username_type = $this->check_username($data['user_name']);
switch($username_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_res = db('user')->where($where)->setField('user_pwd',$data['user_pwd']);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'密码修改成功!');
} else {
$this->return_msg)(400,'密码修改失败!');
}
}
用户绑定邮箱或手机号
User.php中的bind_phone方法和bind_email方法
//绑定手机号
public function bind_phone() {
//接受参数
$data = $this->params;
//检测验证码
$this->check_code($data['phone'],$data['code']);
//修改数据库中的手机号
$db_res = db('user')
->where('user_id',$data['user_id'])
->setField)('user_phone',$data['phone']);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'绑定手机号成功!');
} else {
$this->return_msg(400,'绑定手机号失败!');
}
}
//绑定邮箱
public function bind_email() {
//接受参数
$data = $this->params;
//检测验证码
$this->check_code($data['email'],$data['code']);
//修改数据库中的手机号
$db_res = db('user')
->where('user_id',$data['user_id'])
->setField)('user_email',$data['email']);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'绑定邮箱成功!');
} else {
$this->return_msg(400,'绑定邮箱失败!');
}
}
用户设定昵称
User.php中的set_nickname()方法
//用户设定昵称
public function set_nickname() {
//接收参数
$data = $this->params;
//判断昵称是否存在
$res = db('user')
->where('user_nickname',$data['user_nickname'])
->find();
if($res) {
$this->return_msg(400,'此昵称已被占用!');
}
//修改数据库中对于id的昵称
$db_res = db('user')
->where('user_id',$data['user_id'])
->setField('user_sickname',$data['user_sickname']);
//判断并输出数据
if($db_res !== false) {
$this->return_msg(200,'昵称修改成功!');
} else {
$this->return_msg(400,'昵称修改失败!');
}
}
文章接口
新增文章
Article.php中add_article()方法
public function add_article() {
//接受参数
$data = $this->params;
//增加文章创建时间
$data['article_ctime'] = time();
//增加到数据库中
$db_res = db('article')->insertGetId($data);
//判断并返回结果
if($db_res) {
$this->return_msg(200,'新增文章成功!',$db_res);
} else {
$this->return_msg(400,'新增文章失败!');
}
}
查看文章列表
Article.php中的article_list()方法
public function article_list() {
//接收参数
$data = $this->params;
//设置可选参数
if(!isset($data['num'])) {
$data['num'] = 10;
}
if(!isset($data['page'])) {
$data['page'] = 10;
}
//查询数据库
$count = db('user')
->where('article_uid',$data['user_id'])
->count();
$page_num = ceil($count/$data['num'])
$db_res = $db('article')
-alias('a')
->field('article_id,article_ctime,article_title,user_name')
->join([['user u','u.user_id = a.article_uid']])
->where('user_id',$data['user_id'])
->page($data['page'],$data['num'])
->select();
//判断并返回结果
if($db_res === false) {
$this->return_msg(400,'查询失败!');
} else if(empty($db_res)) {
$this->return_msg(200,'暂无文章!');
} else {
$return['article'] = $db_res;
$return['page_num'] = $page_num;
$this->return_msg(200,'查询成功!',$return);
}
}
查看单个文章
Article.php中的article_detail()方法
public function article_detail() {
//接受参数
$data = $this->params;
//查询数据库文章信息
$db_res = db('article')
->alias('a')
->field('article_id,article_title,article_ctime,article_content,user_name')
->join([['user u','u.user_id = a.article_uid']])
->where('article_id',$data['article_id'])
->find();
$db_res['article_content'] = htmlspecialchars_decode($data['article_content']);
//判断并返回结果
if($res) {
$this->return_msg(200,'查询成功!',$db_res);
} else {
$this->return_msg(200,'查询失败!');
}
}
修改保存文章
Article.php中的update_article()方法:
public function update_article() {
//接收参数
$data = $this->params;
//更新数据库中的文章
$db_res = db('article')
->where('article_id',$data['article_id'])
->update($data);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'文章修改成功!');
} else {
$this->return_msg(240,'文章修改失败!');
}
}
删除文章接口
Article.php中的del_article()方法
public function del_article() {
//接收参数
$data = $this->params;
//删除数据库中指定文章
//物理删除
$db_res = db('article')->delete($data['article_id']);
//逻辑删除
$db_res = db('article')
->where('article_id',$data['article_id'])
->setField('article_isdel',1);
//判断并输出结果
if($db_res !== false) {
$this->return_msg(200,'删除文章成功!');
} else {
$this->return_msg(200,'删除文章失败!');
}
}
路由配置
<?php
use think\Route;
Route::domain('api','api');
//获取验证码
Route::get('code/get_code','code/get_code');
//用户注册接口
Route::post('user/register','user/register');
//用户登录
Route::post('user/login','user/login');
//用户上传头像
Route::post('user/upload_icon','user/upload_icon');
//用户修改密码接口
Route::post('user/change_pwd','user/change_pwd');
//用户找回密码
Route::post('user/find_pwd','user/find_pwd');
//用户绑定手机号
Route::post('user/bind_phone','user/bind_phone');
//用户绑定邮箱
Route::post('user/bind_email','user/bind_email');
//用户设定昵称
Route::post('user/set_nickname','user/set_nickname');
//--------------------------文章接口-----------------------
//新增文章
Route::post('article/add_article','article/add_article');
//查看文章列表
Route::get('article/article_list','article/article_list');
//查看单个文章信息
Route::get('article/article_detail','article/article_detail');
//修改或保存文章
Route::put('article/update_article','article/update_article');
//删除文章
Route::delete('article/del_article','article/del_article');