通过mysql
获取首页的数据为们大致的已经写好了.用的是测试数据库进行测试,现在创建一个Video
视频表.
CREATE TABLE `video` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '视频名称',
`cat_id` smallint(4) unsigned NOT NULL DEFAULT '0' COMMENT '视频板块,在配置目录中',
`image` varchar(200) NOT NULL DEFAULT '' COMMENT '视频封面',
`url` varchar(200) NOT NULL DEFAULT '' COMMENT '视频URL本地',
`type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '视频类型',
`content` text NOT NULL COMMENT '视频简介',
`uploader` varchar(200) NOT NULL DEFAULT '' COMMENT '上传作者',
`video_id` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '阿里云OSS',
`video_duration` int(5) not null default 0 COMMENT '阿里OSS',
`create_time` int(10) unsigned NOT NULL DEFAULT '0',
`update_time` int(10) unsigned NOT NULL DEFAULT '0',
`status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '视频状态-1:已删除,0:禁止播放,1:正常',
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
自己多添加点测试数据哈.到时候再清除呗.对于视频的显示我们应该判断视屏状态,只有status>=1
的才可以显示.
更改Model
.添加
$this->db->where('status',['>=' => 1]);
返回结果
{
"code": 400,
"msg": "Unknown column 'status' in 'where clause' query: SELECT SQL_CALC_FOUND_ROWS * FROM test WHERE status >= ? ORDER BY id DESC LIMIT 5, 5",
"result": null
}
哦,报错了.但是出现了sql的问题.我们不应该直接把错误信息暴露给用户.这样是很不安全滴.所以修改我们的App\HttpController\Api\Index.php
// todo log ==> $e->getMessage();
return $this->writeJson(Status::CODE_BAD_REQUEST, '服务异常');
这种敏感的错误我们写到日志中就好了.千万别暴露出去!更何况是sql语句呢.我这个错误是提示找不到status
.因为之前我们用的test
表.没有更改过来表明所以报错修改App\Model\Model\Video.php
protected $tableName = 'video';
接着先将表里的所有测试数据的create_time和update_time都改成当前的时间戳
update video set create_time= unix_timestamp(now()),update_time= unix_timestamp(now()) where id>=1;
测试可以看到视频的创建时间,修改时间和视频时间
{
...
"video_duration": 123,
"create_time": 1557419871,
"update_time": 1557419871,
...
}
但是这么长的时间戳直接展示给用户.沙雕也用户也看不懂啊.可以在前端做处理,不过还是让牛逼的后段来做处理吧对$data
中的上传时间数据进行修改.如果你是个新手的话可能会这么写.
if(!empty($data['lists'])){
foreach ($data['lists'] as $key => $val){
$data['lists'][$key]['create_time'] = date('Y-m-d H:i:s');
$data['lists'][$key]['update_time'] = date('Y-m-d H:i:s');
}
}
看着是没什么问题,而且本来就没什么问题.我工作第二年的时候还这样写呢~直到遇到我的领导吧.在Review
我代码的时候发现我这样不优雅的写法后对我进行了更正.用起来是蛮舒服的哈.在这里感谢领导,感谢恩师佳奇.总是因为一些微不足道的事夸我给我信息哈
if(!empty($data['lists'])){
foreach ($data['lists'] as &$val){
$val['create_time'] = date('Y-m-d H:i:s');
$val['update_time'] = date('Y-m-d H:i:s');
}
}
这样能少些很多的代码看着也优雅~何不尝试更进一下呢.对于视频时长我们可以在别的网站上看到123秒
的视频格式事00:02:03
.我觉得你们可能会除以60.然后一步步的把数据拼出来,当然也可以但是要写很多代码.而PHP
就有一个定义好的函数直接转换成我们刚才看到的那种格式,我可
if(!empty($data['lists'])){
foreach ($data['lists'] as &$val){
$val['create_time'] = date('Y-m-d H:i:s');
$val['update_time'] = date('Y-m-d H:i:s');
$val['video_duration'] = gmstrftime("%H:%I:%S",$val['video_duration']);
}
}
结果
{
...
"video_duration": "00:12:03",
"create_time": "2019-05-10 00:58:25",
"update_time": "2019-05-10 00:58:25",
...
}
改的挺好的了.接下来可以看下我们的App\HttpController\Api\Index.php
的完整逻辑
public function list()
{
$parm = $this->request()->getRequestParam();
$condition = [];
$page = !empty($parm['page']) ? intval($parm['page']) : 1;
$size = !empty($parm['size']) ? intval($parm['size']) : 5;
if (!empty($parm['cat_id'])) {
$condition['cat_id'] = $parm['cat_id'];
}
try {
$model = new VideoModel();
$data = $model->getVideoData($condition, $page, $size);
} catch (\Exception $e) {
// todo log ==> $e->getMessage();
return $this->writeJson(Status::CODE_BAD_REQUEST, '服务异常');
}
if(!empty($data['lists'])){
foreach ($data['lists'] as &$val){
$val['create_time'] = date('Y-m-d H:i:s');
$val['update_time'] = date('Y-m-d H:i:s');
$val['video_duration'] = gmstrftime("%H:%I:%S",$val['video_duration']);
}
}
return $this->writeJson(Status::CODE_OK, 'ok', $data);
}
关于分页我们用到的场景肯定是不少的.而我们每次都要去执行下面这段代码来获取参数
$parm = $this->request()->getRequestParam();
$condition = [];
$page = !empty($parm['page']) ? intval($parm['page']) : 1;
$size = !empty($parm['size']) ? intval($parm['size']) : 5;
没用到分页一次,我们还得再写一遍(其实也就是复制一遍也没多麻烦..)
就很麻烦.可以把这个抽离出来放到公共的类库中.把刚才的控制器中去掉上面那一坨吧.然后到App\HttpController\Api\Base.php
namespace App\HttpController\Api;
use EasySwoole\Http\AbstractInterface\Controller;
class Base extends Controller
{
public function index()
{
}
public function onRequest(?string $action): ?bool
{
// 如果浏览器没有传uid则任务没有权限。返回无权限
// $uid = $this->request()->getRequestParam('uid');
// if(!$uid){
// $this->writeJson(201,'无权限');
// return false;
// }
// 通过验证执行下面逻辑
return true;
}
/*public function onException(\Throwable $throwable): void
{
// TODO: Change the autogenerated stub
$this->writeJson(501,'请求不合法');
}*/
}
这段代码我之前测试的时候写过一点点.关于为什么定义index
方法这就涉及到了Controller
这个抽象类
的抽象方法
了.前面文章有介绍.想详细了解的话可以看下EasySwoole的基本使用.OnRequst
方法中我注视掉的是对于用户验证.如果没有传uid
就相当于没有权限.只是一个简单的认证小测试,每次用户请求都会走到这里.我们只需要在这里判断用户是否合法就可以了.如果return false
就不会放下走了.我们就把请求来的数据处理放到onRequest
方法中
// 请求的参数数据
public $params = [];
/*获取参数值*/
public function getParmas()
{
$params = $this->request()->getRequestParam();
$params['page'] = !empty($parm['page']) ? intval($parm['page']) : 1;
$params['size'] = !empty($parm['size']) ? intval($parm['size']) : 5;
$this->params = $params;
}
emmm.感觉这个值写死在这不好要不然每次想换个默认值都要上线一次代码.那就把它放到配置中吧.
创建video_page.ini
default_page=1
default_size=5
稍作修改
$params['page'] = !empty($parm['page']) ? intval($parm['page']) : \Yaconf::get('video_page.default_page');
$params['size'] = !empty($parm['size']) ? intval($parm['size']) : \Yaconf::get('video_page.default_size');
在onRequest
调用getParmas
对数据进行处理
public function onRequest(?string $action): ?bool
{
// 如果浏览器没有传uid则任务没有权限。返回无权限
// $uid = $this->request()->getRequestParam('uid');
// if(!$uid){
// $this->writeJson(201,'无权限');
// return false;
// }
// 通过验证执行下面逻辑
$this->getParmas();
return true;
}
修改控制器
public function list()
{
$condition = [];
if (!empty($this->params['cat_id'])) {
$condition['cat_id'] = $this->params['cat_id'];
}
try {
$model = new VideoModel();
$data = $model->getVideoData($condition, $this->params['page'], $this->params['size']);
} catch (\Exception $e) {
// todo log ==> $e->getMessage();
return $this->writeJson(Status::CODE_BAD_REQUEST, '服务异常');
}
if(!empty($data['lists'])){
foreach ($data['lists'] as &$val){
$val['create_time'] = date('Y-m-d H:i:s');
$val['update_time'] = date('Y-m-d H:i:s');
$val['video_duration'] = gmstrftime("%H:%I:%S",$val['video_duration']);
}
}
return $this->writeJson(Status::CODE_OK, 'ok', $data);
}
测试是没有问题的.那是当然,我多牛逼?一行代码也就报个十行错罢了.!!还记得我们对writeJson
方法进行过PSR-4规范的更改吗.我们修改的是源码.但是上线的话我们不可能每次都去更改一遍源码.既然我们继承了Base.php
,而Base.php
又继承了Controller.php
.所以我们可以在Base.php
对writeJson
进行重写.把我们在Controller.php
中写好的直接复制过来就好了
protected function writeJson($statusCode = 200, $msg = null, $result = null)
{
if (!$this->response()->isEndResponse()) {
$data = Array(
"code" => $statusCode,
"msg" => $msg,
"result" => $result
);
$this->response()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$this->response()->withHeader('Content-type', 'application/json;charset=utf-8');
$this->response()->withStatus($statusCode);
return true;
} else {
return false;
}
}
搞定了!写到这么晚了!睡觉!!
哒哒哒哒哒哒多多多多多