最近在做一個基於有讚的多級分銷管理系統,所有成員的店面均在有讚商城,使用有讚API獲得他們的業績,但是有讚提供的分銷只有一級,故製作該系統。考慮到減輕工作量,理清層次關係,採用了OOP設計方法,將資料庫,表封裝為基類,分銷成員,店面等繼承表。
但是在列出銷售量報表和分銷商的時候出現了嚴重性能問題,由於分銷商的業績獎勵是與其下級分銷商掛鉤的,故封裝數據庫的時候,進行了DFS遍歷來獲得所有分銷商的關係樹,然而,在列出銷售報表的時候卻並不需要這樣的關係,DFS在php語言上的時間花銷極大,導致一個頁面打開需要10s以上的時間,故對其進行第一步優化,在資料庫的封裝函數中設定DFS開關:
這個是Database類別的部分實現,其中部分敏感資料已隱藏。
<?php namespace System; require_once('KdtApiClient.php'); class Database { const db_adr=""; const db_usr=""; const db_pwd=""; const db_db=""; public $member=array(); public function init($dfs=true,$store=true) { $mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); $result=$mysqli->query("select `id` from member_new"); $row=$result->fetch_array(); $i=0; while($row) { $this->member[$i]=new Member($row[0],$dfs,$store); $row=$result->fetch_array(); $i++; } $mysqli->close(); } static public function doQuery($string) { $mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); return $mysqli->query($string); } static public function querySell($start,$end) {} }
class Table { public $data=array(); protected $table_name; public function __construct($id) { $this->data['id']=$id; $mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); $result=$mysqli->query("select * from ".$this->table_name." where `id`=$id"); $row=$result->fetch_assoc(); $this->data=$row; $mysqli->close(); } public function updateAll() //Do NOT CHANGE ID!!! { reset($this->data); while($data=each($this->data)) { $querystring="update ".$this->table_name." set `".$data[0]."`='$data[1]' where `id`='".$this->data['id']."'"; Database::doQuery($querystring); } reset($this->data); } public function update($key) { $querystring="update ".$this->table_name." set `$key`='".$this->data[$key]."' where `id`='".$this->data['id']."'"; Database::doQuery($querystring); } public function set($key,$data) //recommended { $this->data[$key]=$data; $this->update($key); } public function get($key) //recommended { return $this->data[$key]; } }
class Member extends Table { protected $table_name="member_new"; public $infer=array(); public $store=array(); public function __construct($id,$dfs=true,$store=true) { parent::__construct($id); $mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); if($dfs){ $result=$mysqli->query("select `id` from ".$this->table_name." where `super`=".$this->data['id']); if($result){ $row=$result->fetch_array(); $i=0; while($row) { $this->infer[$i]=new Member($row[0]); $row=$result->fetch_array(); $i++; } } } if($store) { $result=$mysqli->query("select `id` from store_new where `member`=".$this->data['id']); if($result){ $row=$result->fetch_array(); $i=0; while($row) { $this->store[$i]=new Store($row[0]); $row=$result->fetch_array(); $i++; } } } $mysqli->close(); }
另外,在對前端的AJAX響應的php腳本中,加入緩存的支持,由於有讚的api調用速度較慢,然而這種分銷商城的數據對實時性的要求並不是很高,故採用服務器緩存的方式來減少與有贊通訊這部分導致的速度減緩.另外,本地化的對象代替從遠程數據庫讀取信息,也減少了查詢資料庫的開支.Cache物件的實現如下,將物件的序列化程式碼存於伺服器本地:
<?php namespace System; class Cache { public function __construct() { } static public function readCache($string) { error_reporting(1); $file=fopen($string.".ser","r"); if(!$file)return false; $ser=fread($file,filesize($string.".ser")); fclose($file); $array=array(); $array=unserialize($ser); if(time()-$array['time']>3600*24)return false; return $array['data']; } static public function updateCache($string,$data) { $array=array(); $array['time']=time(); $array['data']=$data; $file=fopen($string.".ser","w"); fwrite($file,serialize($array)); fclose($file); } }
<?php require_once('System/db.php'); require_once('System/cache.php'); use \System\Database; use \System\Cache; switch($_GET['action']) { case 'num': $result=Database::doQuery("select count(*) from member_new"); $row=$result->fetch_array(); echo $row[0]; exit(0); case 'get': if($array=Cache::readCache("member")) { echo json_encode($array); } else { $db=new Database(); $db->init(false,true); $arr=array(); for($i=0;$i<count($db->member);$i++) { $arr[$i]=array(); $arr[$i]=$db->member[$i]->data; $arr[$i]['password']=null; $arr[$i]['name']=iconv("GBK","utf-8",$arr[$i]['name']); $arr[$i]['nickname']=iconv("GBK","utf-8",$arr[$i]['nickname']); $arr[$i]['sell']=$db->member[$i]->getSell(); } Cache::updateCache("member",$arr); echo json_encode($arr); } exit(0);
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
以上就介紹了多級分銷對接第三方API取得資料系統的最佳化,包含了面向的內容,希望對PHP教學有興趣的朋友有所幫助。