PHP缓存技术

 

PHP是一种解释型语言,属于边编译边运行的那种。这种运行模式的优点是程序修改很方便,但是运行效率却很低下。

PHP缓存包括PHP编译缓存和PHP数据缓存两种。

PHP编译缓存针对这种情况做改进处理,使得PHP语言只要运行一次,就可以把程序的编译结果缓存起来。这样,接下来的每次运行都不需要再次编译了,这大大提高PHP运行速度。

PHP数据缓存运用于PHP实际开发之中针对数据处理进行缓存,主要两大方向为:针对数据库数据进行缓存和针对PHP模板数据进行缓存。也可以直接使用NoSQL。

一、技术特点

  • 时间触发缓存

检查文件或数据是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存。

对于缓存文件需要设一个有效时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,但是超过设定的缓存时间,就需要重新从数据库中获取数据, 并生产最新的缓存文件。

比如,将商城的首页就是设置2个小时更新一次。

  • 内容触发缓存

当插入数据或更新数据时,强制更新PHP缓存机制。

例:一个人流量很大的商城,商品很多,商品表必然比较大,这表的压力也比较重;我们就可以对商品显示页进行页面缓存;当商家在后台修改这个商品的信息时,点击保存,我们同时就更新缓存文件;那么,买家访问这个商品信息时,实际上访问的是一个静态页面,而不需要再去访问数据库。

如果对商品页不缓存,那么每次访问一个商品就要去数据库查一次,如果有10万人在线浏览商品,那服务器压力就大了。

  • 静态缓存

​​​​​​​静态化,直接生成HTML或XML等文本文件,有更新的时候重生成一次,适合于不太变化的页面。

二、常用缓存

1.全页面静态化缓存

将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。一般在CMS系统中比较常见。

<?php

/**
 * ob_start()
 * ob_clean()
 * ob_end_clean()
 * ob_flush()
 * ob_end_flush()
 * flush()
 * ob_get_contents()
 *
 */



ob_start();                   //打开“输出控制缓冲”

/* some code 要运行的代码 */

$content = ob_get_contents(); //返回“输出缓冲区的内容”;

/* some code  使用file_put_contents()等函数将返回的数据写入HTML文件 */

ob_end_clean();                  //清空“输出缓冲区”;

小例子:

#建立库
DROP DATABASE IF EXISTS `bigwebcore`;
CREATE DATABASE `bigwebcore` DEFAULT CHARSET utf8;
USE `bigwebcore`;

#建立新闻表
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news`(
	`id` int unsigned not null auto_increment,
	`title` varchar(60) not null,
	`content` varchar(255) not null,
	`filename` varchar(60),
	primary key(`id`)
)ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

INSERT INTO news(`title`,`content`) values('hello1','四川你好!');
INSERT INTO news(`title`,`content`) values('hello2','北京你好!');
<?php
header("Content-Type:text/html;charset=utf-8");

$db_host = 'localhost';
$db_port = 3306;
$db_name = 'bigwebcore';
$db_user = 'root';
$db_pwd  = '123456';
$static  = 'static';

$conn = mysql_connect($db_host,$db_user,$db_pwd) or die("数据库连接失败:".mysql_error());
mysql_query("set names utf8",$conn);
mysql_select_db($db_name,$conn);


if($_GET){
	if($_GET['id']){
		$id = intval($_GET['id']);

		$html_filename = 'news-id-'.$id.'.html';
		if(file_exists($html_filename) && filemtime($html_filename)+30 > time()){
			echo file_get_contents($html_filename);
			mysql_close();
			exit;
		}

		$sql = "SELECT * FROM `news` WHERE id='{$id}'";
		$result = mysql_query($sql,$conn);

		ob_start();
		if($row = mysql_fetch_array($result)){
			echo "<meta charset=utf-8>";
			echo "<table border='1' bordercolor='green' cellspacing='0' width='400px' height='200px'>";
			echo "<tr><th>新闻详情</th></tr>";
			echo "<tr><td>{$row['title']}</td></tr>";
			echo "<tr><td>{$row['content']}</td></tr>";
			echo "</table>";
		}else{
			echo "没有任何内容。";
		}
		mysql_free_result($result);
		$html_content = ob_get_contents();
		file_put_contents($static.'/'.$html_filename, $html_content);
		//ob_end_flush();
	}else{
		echo "非法请求!";
	}
}else{
	$sql = "SELECT * FROM `news`";
	$result = mysql_query($sql,$conn);
	echo "<h1>新闻列表</h1>";
	echo "<a href='#'>添加新闻</a><hr />";
	echo "<table>";
	echo "<tr><th>ID</th><th>标题</th><th>查看详情</th></tr>";
	while($row = mysql_fetch_row($result)){
		echo "<tr><td>{$row[0]}</td><td>{$row[1]}</td><td><a target='_blank' href='news.php?id={$row[0]}'>查看内容</a></td></tr>";
	}
	echo "</table>";
	mysql_free_result($result);
}

mysql_close();
2.页面部分缓存

将页面中不常变动的部分进行静态化缓存,而经常变化的部分不缓存,最后组装在一起显示。

可以使用类似ob_get_contents()的方式实现,也可以利用类似ESI之类的页面片段缓存策略,使其用来做动态页面中相对静态的片段部分的缓存。

该缓存方式常用于商城中的商品页。

3.数据缓存

缓存数据的一种方式。

这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓存表或文件中获得。

例一:商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息等数据,此时就可以将这些 数据缓存到一个php文件中,文件名包含商品id来建一个唯一标示;下一次有人想查看这个商品时,首先就直接调这个文件里面的信息,而不用再去数据库查询;缓存文件中缓存的就是一个php数组之类的。Ecmall商城系统里面就用了这种方式。

例二:多表关联的时候,把附表中的内容生成数组保存到主表的一个字段中,需要的时候数组分解一下,这样的好处是只读一个表,坏处就是两个数据同步会多不少步骤,数据库永远是瓶颈,用硬盘换速度,是这个的关键点。

4.查询缓存

其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询得到的数据缓存在一个文件中,下次遇到相同的查询时,就直 接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就需要以查询语句为基点来建立唯一标示(md5($sql)等方式)。 

5.内存缓存

使用redis,memcached等nosql数据库设置PHP缓存,通过缓存查询结果,来减少数据库的访问次数,从而提高网站的响应速度、 提高可扩展性。

memcache:

<?php
	$memcache = new \Memcache;             //创建一个memcache对象
    $memcache->connect('localhost', 11211) or die ("Could not connect"); //连接Memcached服务器
    $memcache->set('key', 'test');        //设置一个变量到内存中,名称是key 值是test
    $get_value = $memcache->get('key');   //从内存中取出key的值
    echo $get_value;

redis:

<?php
   //连接本地的 Redis 服务

    $redis = new \Redis();
    $redis->connect('127.0.0.1', 6379);
    echo "Connection to server sucessfully";

    //查看服务是否运行
    echo "<br />";
    echo "Server is running: " . $redis->ping();

    //String字符串
    echo "<br />";
    $redis->set('test','test123');
    echo $redis->get('test');

    //List列表
    echo "<br />";
    $redis->lpush('zck','zck1');
    $redis->lpush('zck','zck2');
    $redis->lpush('zck','zck3');
    $arList = $redis->lrange('zck',0,2);
    print_r($arList);

    //Keys
    echo "<br />";
    $arKeys = $redis->keys('*');
    print_r($arKeys);

memcache、redis、MongoDB等NoSQL这儿只做了简单演示,实际使用会相对复杂得多。需要专门的专题或章节来讨论。

6.apache缓存模块

apache安装完以后,是不允许被cache的。

如果外接了cache或squid服务器要求进行web加速的话,就需要在htttpd.conf里进行设 置,前提是在安装apache的时候要激活mod_cache的模块。 

安装apache时:./configure --enable-cache --enable-disk-cache --enable-mem-cache 

7.PHP APC缓存

Php有一个APC缓存扩展,windows下面为php_apc.dll,需要先加载这个模块,然后是在php.ini里面进行配置: 
[apc]  
     extension = php_apc.dll  
     apc.rfc1867 = on  
     upload_max_filesize = 100M  
     post_max_size = 100M  
     apc.max_file_size = 200M  
     upload_max_filesize = 1000M  
     post_max_size = 1000M  
     max_execution_time = 600 ;   #每个PHP页面运行的最大时间值(秒),默认30秒  
     max_input_time = 600 ;            #每个PHP页面接收数据所需的最大时间,默认60  
     memory_limit = 128M ;             #每个PHP页面所吃掉的最大内存,默认8M 

8.Opcode缓存

Zend引擎执行PHP流程:

​​​​​​​

  1. 将PHP代码转换为语言片段(Tokens)
  2. 将Tokens转换成简单而有意义的表达式
  3. 将表达式编译成Opocdes
  4. 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能返

所以,对于相同的php文件,第一次运行时可以缓存其Opcodes码,下次再执行这个页面时,直接会去找到缓存下的Opcodes码,直接执行最后一步,而不再需要中间的步骤了。

比较知名的是XCache、Turck MM Cache、PHP Accelerator等。

关于Opcodes:http://www.laruence.com/2008/06/18/221.html

转载于:https://my.oschina.net/programs/blog/1788847

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值