0

0

使用etag和文件缓存降低服务器数据库压力

PHP中文网

PHP中文网

发布时间:2016-05-23 16:38:50

|

1619人浏览过

|

来源于php中文网

原创

使用php5.3+,使用了一些自定义的内容,不过都一看便知
比如常量root、dir_cache等
核心使用的有
diehere(输出json字符串,并die),err_a(组合错误信息),makedir(连续创建目录)
其余的都根据实际使用的情况来

终于debug完成了……新增one_key方法,一键完成输出,完美……
departments初次查询170ms
之后仅16ms,越复杂效果越好啊

高复杂测试get_users_complex.php
初次108.0 kb  985ms
第二次16ms,哈哈哈,
清空etag(未清空data)读取,接收数据125ms                        

1. [代码]DEF.inc.php    

	define('ROOT',dirname(__FILE__));

	define('CLS_SCACHER','/inc/SCACHER.cls.php');
	define('CLS_ECACHER','/inc/ECACHER.cls.php');

	define('DIR_CACHE','/cache/');	//用于缓存判断的目录


function run_sql($sql){
	static $db;
	if(!$db){
		$db=getdb();
	}
	return mysql_query($sql,$db);
}

function getdb(){
	static $mydb;
	if(!$mydb){
		$mydb=dbconnection();
	}
	return $mydb;
}

function dbconnection(&$var=0){
	
	if($var==0||!is_array($var)){$var=array();}
	if(!isset($var['dbhost']) || !is_string($var['dbhost'])){	$var['dbhost']=constant('DBHOST');}
	if(!isset($var['dbuser']) || !is_string($var['dbuser'])){	$var['dbuser']=constant('DBUSER');}
	if(!isset($var['dbpsw']) || !is_string($var['dbpsw'])){$var['dbpsw']=constant('DBPSW');}
	$db=mysql_connect($var['dbhost'],$var['dbuser'],$var['dbpsw']) or die();
	if(!$db){return 0;}
	mysql_select_db(constant('DBNAME'),$db) or die();//echo('db enter here');
	mysql_query("SET NAMES 'UTF8'");
	return $db;
}

function PR($v){
	if(isset($v)){
		echo('
');
		print_r($v);
		echo('
'); } } function rs_2_array($rs){ //this is a function used to make the code clear and less //i am tired to code same code to get the arry result //thought it is not much //redlz2500@2008-06-24 $t=array(); try { while($row=mysql_fetch_array($rs,MYSQL_ASSOC)){ $t[]=$row; } return $t; }catch (Exception $e) { } return $t; } /*  * 功能:连续建目录  * $dir 目录字符串  */ function makedir($dir,$mode = '0777') { //notice: the $dir will not set the code style & //as maybe call by $str.$str1 //the var can not be reference if(!isset($dir)){return 0;} //echo('
**********intomakedir*************
'.$dir); $dir = str_replace( "\\", "/", $dir ); $mdir = ""; foreach( explode( "/", $dir ) as $val ) { $mdir .= $val."/"; if( $val == ".." || $val == "." ) continue; if( ! file_exists( $mdir ) ) { if(!@mkdir( $mdir, $mode )){ echo "创建目录 [".$mdir."]失败."; exit;    }   } } return true; }

2. [代码]CLS_SCACHER   

scacher($opt);
		}
		
		public function scacher($opt=[]){
			$flag=false;
			if($opt['category'] && is_string($opt['category']) && ($this->category!=$opt['category']) ){
				$this->category=$opt['category'];
				$flag=true;
			}
			if($opt['name'] && is_string($opt['name']) && ($this->name!=$opt['name'])){
				$this->name=$opt['name'];
				$flag=true;
			}
			if($opt['path'] && is_string($opt['path']) && ($this->pat!=$opt['path'])){
				$this->path=$opt['path'];
				$flag=true;
			}
			if($flag){
				if($this->path){
					$this->fullpath=ROOT.DIR_CACHE.$this->path.'/';
				}else{
					$this->fullpath=ROOT.DIR_CACHE;
				}
				if(!file_exists($this->fullpath)){
					makedir($this->fullpath);
					if(!file_exists($this->fullpath)){
						throw new Exception('errSCACHER配置失败 当前调用参数:'.$this->category.'.'.$this->name);
					}
				}
			}
		}
		
		public function set($v){
			$fp=fopen($this->fullpath . $this->category .'.'. $this->name,'w');
			if (!fwrite($fp,$v)) {
				return ['success'=>false,'error'=>err_a('errSCACHER_1','数据写入失败,请稍后重试。
重试无效请联系管理员。
当前调用参数:'.$this->category.'.'.$this->name)]; } @fclose($fp); return ['success'=>true]; } public function get(){ $f=$this->fullpath . $this->category .'.'. $this->name; if(file_exists($f)){ $res=@file_get_contents($f); if(!$res){ $res=''; } return ['success'=>true,'data'=>$res]; }else{ return ['success'=>false,'data'=>'','error'=>err_a('errSCACHER_3','未找到缓存。
当前调用参数:'.$this->category.'.'.$this->name)]; } } public function del(){ $f=$this->fullpath . $this->category .'.'. $this->name; if(file_exists($f)){ @unlink($f); if(file_exists($f)){ return ['success'=>false,'error'=>err_a('errSCACHER_2','数据处理异常,请稍后重试。
重试无效请联系管理员。
当前调用参数:'.$this->category.'.'.$this->name)]; } }else{ return ['success'=>true]; } } } ?>

3. [代码]CLS_ECACHER    

scacher=new scacher([]);		//scacher实例,路径由scacher来控制
			$this->ecacher($opt);
		}
		
		public function __destruct(){
			
		}
		
		function ecacher($opt){
			if(is_array($opt)){
				if($opt['force_cache']){
					$this->force_cache=true;
				}else{
					if(isset($opt['force_cache'])){
						$this->force_cache=false;
					}
				}
				if($opt['path'] && is_string($opt['path'])){
					$this->path=$opt['path'];
				}
				if($opt['category'] && is_string($opt['category'])){
					$this->category=$opt['category'];
				}
				if($opt['name'] && is_string($opt['name'])){
					$this->name=$opt['name'];
				}
				if(isset($opt['auto_send_etag_header'])){
					$this->auto_send_etag_header=$opt['auto_send_etag_header'];
				}
				if($opt['create_fn'] && is_string($opt['create_fn'])){
					$this->create_fn=$opt['create_fn'];
				}
				if($opt['create_par']){
					if(is_array($opt['create_par'])){
						$this->create_par=$opt['create_par'];
					}else{
						$this->create_par=[$opt['create_par']];
					}
				}else{
					$this->create_par=[];
				}
				$this->scacher->scacher($opt);//更新的数据写入(好吧,其实并没有什么卵用)(好吧,可以提前判断缓存路径有没有效)
			}
		}
		
		private function mode_etag(){
			$this->scacher->scacher(['name'=>$this->name.'.etag']);
		}
		private function mode_data(){
			$this->scacher->scacher(['name'=>$this->name.'.']);
		}
		public function etag_chk(){
			$this->mode_etag();//设置etag模式
			$etag=$this->scacher->get();
			echo_debug('test etag');
			echo_debug($etag);
			if($etag['success']){
				$etag=$etag['data'];
			}else{
				return $etag;
			}
			$s_etag=$_SERVER['HTTP_IF_NONE_MATCH'];
			echo_debug('etag from browse');
			echo_debug($s_etag);
			if($etag){
				if($s_etag==$etag){
					if($this->auto_send_etag_header){
						if($this->force_cache){
							header('Cache-Control: max-age=0');
							header('Expires: '.gmdate('D, d M Y H:i:s', time() + SERVER_TIME_SHIFT + 10 ) . ' GMT' );
						}
						header('Etag:'.$etag,true,304);
						die();//必须die,否则还会继续执行下去。
					}else{
						return [	'etag'=>$etag,	'statue'=>DEF_ECACHE_PERFECT	];
					}
				}else{
					if($this->auto_send_etag_header){
						if($this->force_cache){
							header('Cache-Control: max-age=0');
							header('Expires: '.gmdate('D, d M Y H:i:s', time() + SERVER_TIME_SHIFT + 10 ) . ' GMT' );
						}
						header('Etag:'.$etag);
					}
					return [	'etag'=>$etag,	'statue'=>DEF_ECACHE_BROWSER_NULL	];
				}
			}else{
				return [
					'etag'=>'',
					'statue'=>DEF_ECACHE_ETAG_NULL
				];
			}
		}
		
		public function etag_create($auto=false){
			$etag=md5($this->category.':'.$this->name.':'.time().':'.ranstr());
			$this->mode_etag();
			$this->scacher->set($etag);
			if($auto){
				if($this->force_cache){
					header('Cache-Control: max-age=0');
					header('Expires: '.gmdate('D, d M Y H:i:s', time() + SERVER_TIME_SHIFT + 10 ) . ' GMT' );
				}
				header('Etag:'.$etag);
			}
			echo_debug('etag create finish:'.$etag);
			return [
				'success'=>true,
				'etag'=>$etag,
				'status'=>DEF_ECACHE_ETAG_CREATED
			];
		}
		
		public function data_get(){
			//PR('begin get data');BR();
			$this->mode_data();
			$data=$this->scacher->get();
			if($data['success']){
				echo_debug('orgin data is:');
				echo_debug($data['data']);
				$data['data']=unserialize($data['data']);
			}else{
				echo_debug('not success:');
				echo_debug($data);
				$data['data']='';
			}
			echo_debug();
			echo_debug('the data is:');
			echo_debug($data);
			return $data;
		}
		public function data_create($auto_etag=false){
			if(!$this->create_fn){
				throw new Exception('未传递数据生成函数
当前参数:'.$this->category.'.'.$this->name); //这样的错误时不允许的,因此直接抛出错误 die(); } $data=call_user_func_array($this->create_fn,$this->create_par); //生成数据的处理 if($data===false){ throw new Exception('生成数据失败
当前参数:'.$this->category.'.'.$this->name); //无法,只有不返回false了 die(); } //PR($data); $s_data=serialize($data); $this->mode_data(); $res=$this->scacher->set($s_data); if(!$res['success']){ return $res; } if($auto_etag){ $res=$this->etag_create(); if(!$res['success']){ return $res; } } return ['success'=>true,'data'=>$data]; } public function clear($p=['etag','data']){ if(in_array('both',$p)){ $p=['etag','data']; } if(in_array('etag',$p)){ $this->mode_data(); $res=$this->scacher->del(); if(!$res['success']){ return $res; } } if(in_array('etag',$p)){ $this->mode_etag(); $res=$this->scacher->del(); if(!$res['success']){ return $res; } } return ['success'=>true]; } public function one_key(){ $r=$this->etag_chk(); if(!$r['etag']){ echo_debug('the etag is null,should be rebuild'); echo_debug($r); $this->etag_create('auto'); } $res=$this->data_get(); if($res['success']){ //PR($res); if($res['data']){ diehere($res); } } echo_debug('recreate data'); $data=$this->data_create(); diehere($data); } } ?>

4. [代码]get_departments.php  

'get_departments',
		'path'=>'json','category'=>'common','name'=>'department'
	]);
	
	$e->one_key();
	
	die();
function get_departments(){
	$sql='select `depid` as `id`,`name`,`father`,`departcode` as `code` from `department` where `father` !=0';
	
	$rs=run_sql($sql);
	$data=[];
	require_once(ROOT.INC_MAIL);
	while($row=mysql_geta($rs)){
		$address=get_dep_mail_address($row['id']);
		$fullname=explode('.',$address);
		$fullname=array_reverse($fullname);
		$fullname=implode('.',$fullname);
		$row['fullname']=$fullname;
		$data[]=$row;
	}
	return $data;
}
?>

5. [代码]get_users.php  

'get_users',
		'create_par'=>$par['depid'],
		'path'=>'json','category'=>'common','name'=>'users_in_'.$par['depid']]);
	
	$e->one_key();
	
function get_users($depid){
	$sql='select `uid`,`name`,`login`,`depid` from `user` where `register` = 1 and `depid` = '.$depid;
	$rs=run_sql($sql);
	$rs=rs_2_array($rs);
	return $rs;
}

?>

6. [代码]get_users_complex.php  

'get_users',
		'create_par'=>$par['depid'],
		'path'=>'json','category'=>'common','name'=>'users_all']);
	
	$e->one_key();
	
function get_users(){
	$sql='select `uid`,`name`,`login`,`depid` from `user` where `register` = 1 ';
	$rs=run_sql($sql);
	require_once(ROOT.INC_MAIL);
	$data=[];
	while($row=mysql_geta($rs)){
		$addr=_get_user_mail_address($row['login']);
		$row['addr']=$addr;
		$data[]=$row;
	}
	return $data;
}

?>

                   

网博士中英文外贸企业网站源码
网博士中英文外贸企业网站源码

系统简介系统三大特色:1、全静态:全站生成.html静态页面。降低服务器压力,增强百度收录。2、高优化:特别针对搜索引擎进行优化处理,让客户快速找到你。3、够简单:拥有完善后台管理系统,所有内容均可在后台进行更新。非专业人士也可操作。网站后台后台管理地址:http://你的网站域名/Admin/login.asp用户名:admin密码:admin后台文件夹名:Admin数据库存放位置:Data21

下载

                   

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号