[Laravel] 12 - WEB API : cache implement

前言


Ref: https://www.imooc.com/video/2873php

服務端如何爲客戶端(app)的首頁提供數據接口,html

本篇用此做爲例子演示接口的實現。mysql

 

 

 

單例模式


1、三大原則

  • 單例實現
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;   } }

該類返回一個可用的數據庫鏈接。sql

 

 

2、單例模式連接數據庫

  • 鏈接類設計

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)

 

 

 

首頁接口


1、大綱

 

 

2、方案一

  • 流程

  • 代碼
<?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參數能夠取到,可是不合法的。服務器

  • 文檔

補充:實現接口,固然也要建立相應的接口文檔,以下。app

 

  • 完整的代碼

[list.php]ide

<?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。 

 

 

3、方案二

  • 流程圖

進一步地,咱們開始考慮如何利用緩存。

 

  • 利用緩存訪問首頁

[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); }

 

 

 4、方案三

  • 流程圖

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;
相關文章
相關標籤/搜索