Heim  >  Artikel  >  Backend-Entwicklung  >  多级分销对接第三方API获取数据系统的优化

多级分销对接第三方API获取数据系统的优化

WBOY
WBOYOriginal
2016-08-08 09:20:201293Durchsuche

最近在做一个基于有赞的多级分销管理系统,所有成员的店面均在有赞商城,使用有赞API获得他们的业绩,但是有赞提供的分销只有一级,故制作该系统。考虑到减轻工作量,理清层次关系,采用了OOP设计方法,将数据库,表封装为基类,分销成员,店面等继承表。

但是在列出销售量报表和分销商的时候出现了严重性能问题,由于分销商的业绩奖励是与其下级分销商挂钩的,故封装数据库的时候,进行了DFS遍历来获得所有分销商的关系树,然而,在列出销售报表的时候却并不需要这样的关系,DFS在php语言上的时间花销极大,导致一个页面打开需要10s以上的时间,故对其进行第一步优化,在数据库的封装函数中设置DFS开关:

这个是Database类的部分实现,其中部分敏感数据已隐藏。

<?php namespace System;
require_once(&#39;KdtApiClient.php&#39;);
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)
        {}
}

member类是继承自Table:

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];
	}

}

封装了对表的基本操作,简化以后的代码编写.下面member类的构造函数可以完成DFS功能,加设开关参数后,可以在某些场合不试用DFS而大大提升效率:

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[&#39;time&#39;]>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);
        }
    }

后端AJAX响应页面根据Cache类的反馈选择获取本地数据,或是请求服务器更新本地数据:

<?php require_once(&#39;System/db.php&#39;);
require_once(&#39;System/cache.php&#39;);
use \System\Database;
use \System\Cache;

switch($_GET[&#39;action&#39;])
{
	case &#39;num&#39;:
		$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>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);</count>

经过以上优化,原本响应时间在15s左右的页面,现在响应时间为0.5s左右.

版权声明:本文为博主原创文章,未经博主允许不得转载。

以上就介绍了多级分销对接第三方API获取数据系统的优化,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:PHP生成百万个UID存入文件Nächster Artikel:PHP 真正多线程的使用