[Laravel] 12 - WEB API : cache implement
前言
Ref: https://www.imooc.com/video/2873
服务端如何为客户端(app)的首页提供数据接口,
本篇用此作为例子演示接口的实现。
单例模式
一、三大原则
- 单例实现
class Db {
static private $_instance;
static private $_connectSource; private $_dbConfig = array(
'host' => 127.0.0.1',
'user' => 'root',
'password' => '',
'database' => 'video', );
private function __construct() {
} static public function getInstance() {
if (!self::$_instance instanceof self)) {
self::$_instance = new self(); # 实例化的方法有点小意思
} return self::$_instance;
}
}
该类返回一个可用的数据库连接。
二、单例模式链接数据库
- 连接类设计
Ref: http://www.runoob.com/php/func-mysqli-select-db.html
Ref: http://www.w3school.com.cn/php/func_mysql_query.asp
public function connect() {
if (!self::$_connectSource) { # step 1, 连接
self::$_connectSource = mysql_connect($this->_dbConfig['host'],
$this->_dbConfig['user'],
$this->_dbConfig['password']);
if (!self::$_connectSource) {
die('mysql connect error' . mysql_error());
} mysql_select_db($this->_dbConfig['database'], self::$_connectSource)
$sql = "SELECT * FROM Person";
mysql_query($sql, self::$_connectSource);
}
return self::$_connectSource;
}
- 数据库链接
$connect = Db::getInstance()->connect();
var_dump($connect); Output:
resource(3, mysql link)
- 查询数据库
$connect = Db::getInstance()->connect(); $sql = "select * from video";
$result = mysql_query($sql, $connect); echo mysql_num_rows($result)
var_dump($result); [Output]
2
resource(4, mysql result)
首页接口
一、大纲
二、方案一
- 流程
- 代码
<?php require_once('./response.php');
require_once('./db.php');
# 解析URL
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$pageSize = isset($_GET['pagesize']) ? $_GET['pagesize'] : 1; if (!is_numeric($page) || !is_numberic($pageSize)) {
return Response::show(401, "数据不合法”);
} # sql语句的构造
$offset = ($page - 1) * $pageSize;
$sql = "select * from video where status = 1 order by orderby desc limit " . $offset. "," . $pageSize; # 连接数据库
$connect = Db::getInstance()->connect();
$result = mysql_query($sql, $connect);
var_dump($result);
- 测试
URL: app.com/list.php?format=xml&page=xxxxx
page参数可以取到,但是不合法的。
- 文档
补充:实现接口,当然也要创建相应的接口文档,如下。
- 完整的代码
[list.php]
<?php
// http://app.com/list.php?page-=1&pagesize=12
require_once('./response.php');
require_once('./file.php');
------------------------------------------------------------------
$file = new File();
$data = $file->cacheData('index_cron_cahce');
if($data) {
return Response::show(200, '首页数据获取成功', $data);
}else{
return Response::show(400, '首页数据获取失败', $data);
}
exit; ------------------------------------------------------------------
require_once('./db.php');
require_once('./file.php');
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$pageSize = isset($_GET['pagesize']) ? $_GET['pagesize'] : 6;
if(!is_numeric($page) || !is_numeric($pageSize)) {
return Response::show(401, '数据不合法');
}
------------------------------------------------------------------
$offset = ($page - 1) * $pageSize;
$sql = "select * from video where status = 1 order by orderby desc limit ". $offset ." , ".$pageSize; ------------------------------------------------------------------
$cache = new File();
$videos = array();
if(!$videos = $cache->cacheData('index_mk_cache' . $page .'-' . $pageSize)) {
echo 1;exit; --------------------------------------------------------------
try {
/**
* 连接方法,如果连接失败了,通过异常处理方式解决
*/
$connect = Db::getInstance()->connect();
} catch(Exception $e) {
// $e->getMessage(); 仅用于调试模式
return Response::show(403, '数据库链接失败');
} --------------------------------------------------------------
$result = mysql_query($sql, $connect);
while($video = mysql_fetch_assoc($result)) {
$videos[] = $video;
} /**
* 获得了sql的查询结果,然后在结果中一行行读取构成一个我们熟悉的数组的形式:videos[]
* 这个结果可以之后以缓存的形式存在下去。
*/
if($videos) {
$cache->cacheData('index_mk_cache' . $page .'-' . $pageSize, $videos, 1200);
}
}
------------------------------------------------------------------
if($videos) {
return Response::show(200, '首页数据获取成功', $videos);
} else {
return Response::show(400, '首页数据获取失败', $videos);
}
mysql_fetch_assoc:
从结果集中取得一行作为关联数组。返回根据从结果集取得的行生成的关联数组,如果没有更多行,则返回 false。
三、方案二
- 流程图
进一步地,我们开始考虑如何利用缓存。
- 利用缓存访问首页
[1] 对静态缓存的改进
在我获取的时候:缓存文件时间 + 缓存失效时间 与 当前时间 做个对比。
通过以下字符串截取手段获取 cacheTime & value。
$contents = file_get_contents($filename); $cacheTime = (int)substr($contents, 0 ,11); # 把缓存失效时间截取出来
$value = substr($contents, 11); # 截取value /**
* cacheTime = 0 表示永久有效
*/
if($cacheTime !=0 && ($cacheTime + filemtime($filename) < time())) {
unlink($filename); # 删除缓存文件
return FALSE;
}
[2] 调用静态缓存
<?php
// http://app.com/list.php?page-=1&pagesize=12
require_once('./response.php');
require_once('./db.php');
require_once('./file.php');
------------------------------------------------------------------
$file = new File();
$data = $file->cacheData('index_cron_cahce');
if($data) {
return Response::show(200, '首页数据获取成功', $data);
}else{
return Response::show(400, '首页数据获取失败', $data);
}
exit; ------------------------------------------------------------------
require_once('./db.php');
require_once('./file.php'); $page = isset($_GET['page']) ? $_GET['page'] : 1;
$pageSize = isset($_GET['pagesize']) ? $_GET['pagesize'] : 6; if(!is_numeric($page) || !is_numeric($pageSize)) {
return Response::show(401, '数据不合法');
} ------------------------------------------------------------------
$offset = ($page - 1) * $pageSize;
$sql = "select * from video where status = 1 order by orderby desc limit ". $offset ." , ".$pageSize; ------------------------------------------------------------------
$cache = new File();
$videos = array(); if( !$videos = $cache->cacheData('index_mk_cache' . $page .'-' . $pageSize) ) {
echo 1;exit; # 说明缓存失效
# If 缓存失效,则如下读取数据库,当然之后也要设置新的缓存
--------------------------------------------------------------
try {
/**
* 连接方法,如果连接失败了,通过异常处理方式解决
*/
$connect = Db::getInstance()->connect(); } catch(Exception $e) {
// $e->getMessage(); 仅用于调试模式
return Response::show(403, '数据库链接失败');
} --------------------------------------------------------------
$result = mysql_query($sql, $connect);
while($video = mysql_fetch_assoc($result)) {
$videos[] = $video;
} /**
* 获得了sql的查询结果,然后在结果中一行行读取构成一个我们熟悉的数组的形式:videos[]
* 这个结果可以之后以缓存的形式存在下去。
*/ if($videos) {
$cache->cacheData('index_mk_cache' . $page .'-' . $pageSize, $videos, 1200);
}
}
# If 缓存已存在,则直接读取缓存数据 in $videos 就好了
------------------------------------------------------------------
if($videos) {
return Response::show(200, '首页数据获取成功', $videos);
} else {
return Response::show(400, '首页数据获取失败', $videos);
}
四、方案三
- 流程图
1. 掌握如何编写定时脚本程序
2. 理解服务器如何提前准备数据
提前准备好,而不是第一次通过数据库的方式。
我们希望的是:第一次就铜鼓缓存获取数据,这个缓存的内容是定时导入的。
- 定时任务
cron.php定时执行 list.php。
[list.php]
<?php // 让crontab定时执行的脚本程序 */5 * * * * /usr/bin/php /data/www/app/cron.php
// 目的:想获取video表中 6条数据 require_once('./db.php');
require_once('./file.php'); $sql = "select * from video where status = 1 order by orderby desc";
try {
$connect = Db::getInstance()->connect();
} catch(Exception $e) {
// $e->getMessage();
file_put_contents('./logs/'.date('y-m-d') . '.txt' , $e->getMessage()); # 记录日志
return;
}
$result = mysql_query($sql, $connect);
---------------------------------------------------------------------------------------
$videos = array();
while($video = mysql_fetch_assoc($result)) {
$videos[] = $video;
}
---------------------------------------------------------------------------------------
$file = new File();
if($videos) {
$file->cacheData('index_cron_cahce', $videos); # 默认是永久有效的
} else {
file_put_contents('./logs/'.date('y-m-d') . '.txt' , "没有相关数据");
}
return;
[Laravel] 12 - WEB API : cache implement的更多相关文章
- [Laravel] 11 - WEB API : cache & timer
前言 一.资源 Ref: https://www.imooc.com/video/2870 二.缓存 缓存:静态缓存.Memcache.redis缓存 Ref: [Laravel] 09 - Func ...
- [Laravel] 10 - WEB API : wrapper
前言 一.常用的解决方案 React 前端 + PHP (Laravel) 后端 Such as "some exposure to WEB API’s and/or RESTful“. 使 ...
- [Laravel] 13 - WEB API : update & error tracking
前言 一.大纲 Ref: https://www.imooc.com/video/3134 版本升级分析以及数据表设计 版本升级分析 掌握如何设计版本升级数据表 版本升级接口开发以及APP演示 二.数 ...
- [Laravel] 14 - REST API: Laravel from scratch
前言 一.基础 Ref: Build a REST API with Laravel API resources Goto: [Node.js] 08 - Web Server and REST AP ...
- Implement JSON Web Tokens Authentication in ASP.NET Web API and Identity 2.1 Part 3 (by TAISEER)
http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-an ...
- Asp.Net Web API中使用Session,Cache和Application的几个方法
在ASP.NET中,Web Api的控制器类派生于ApiController,该类与ASP.NET的Control类没有直接关系,因此不能像在Web MVC中直接使用HttpContext,Cache ...
- [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...
- laravel 配置路由 api和web定义的路由的区别详解
1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...
- 循序渐进学.Net Core Web Api开发系列【12】:缓存
系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如 ...
随机推荐
- April Fools Contest 2017 题解
趁着上课无聊,来补一补-- A. Numbers Joke 直接oeis就好了:http://oeis.org/search?q=numbers+joke&language=english&a ...
- spring源码分析系列 (2) spring拓展接口BeanPostProcessor
Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...
- centos7安装单机rocketmq,图文教程
系统环境 1.操作系统:64位CentOS Linux release 7.2.1511 (Core) 2.jdk版本:1.8.0_121 3.IP地址:192.168.1.210 下载rocketm ...
- __x__(24)0907第四天__ display 和 visibility
<a>百度</a> 也是内联元素,无法设置width和height <img>可以设置width和height,但是不会占用一行,所以是典型的行内块元素inl ...
- 手把手教你用CAB发布OCX的简单办法
CAB是一种文件压缩格式,把OCX文件(ActiveX插件)压缩成CAB文件是为了发布它,这种发布方式给人感觉“浏览器会自动安装该插件”,很多朋友钟情于此.目前流行很多压缩工具,但WINRAR这类工具 ...
- Gradle Build Tool
转自知乎: nonesuccess 通俗的说:gradle是打包用的. 你觉得解决你的问题了吗?如果没解决,那是你的问题提得不够好.比如我猜你应该提:为什么要打包发布,打包发布有几种常见方法,为什么这 ...
- Windows 下使用 MinGW 和 CMake 进行开发
CMake 是个非常棒的项目管理工具,这已经是毋庸置疑的. 一些小工具需要在 win 下开发,所以今天探索使用 MinGW 和 CMake 在 win 下的搭配使用.简单做记录. MinGW 使用 Q ...
- 【转】苹果App Store审核指南中文翻译(更新)
(注:<苹果应用商店审核指南>中文翻译最近一次更新为2013-03-04,文中红色部分是相对于2013-03-04版本的新增内容,绿色部分代表更改的内容,蓝色表示苹果相关官方文档的链接.) ...
- 基于ubuntu搭建 Discuz 论坛
系统要求:Ubuntu 16.04.1 LTS 64 位操作系统 安装 Apache2 ubuntu 需要安装 Apache2 ,使用 apt-get 安装 Apache2(安装好后,您可以通过访问实 ...
- Springmvc 整合 jetbrick 实例
应用环境: <jetbrick.version>1.2.8</jetbrick.version> <antlr4-runtime.version>4.2.2< ...