使用php数据缓存技术提高执行效率

时间:2023-05-24 23:14:24 

为什么要使用php缓存技术?理由很简单:提高效率。在程序开发中,获取信息的方式主要是查询数据库,除此以外,也可能是通过Web Services或者别的某种方法,无论哪种方法,在大量的并发访问面前,它们都可能成为效率的瓶颈,为了解决这些问题,人们提出了很多解决方案,其中一些是利用优化软件(如:APC,Eaccelerator,Zend Optimizer等等)来提高程序的运行效率,合理的运用这些软件,往往能使程序的运行效率得到数量级上的提升,但前提是你必须拥主机的控制权,以便能够安装这些软件,如果你使用的是虚拟主机的话,那么只能祈祷你的服务提供商已经预装了某个优化软件,否则就必须自己使用PHP来实现相应的缓存功能。

PHP缓存技术是一种解释型语言,属于边编译边运行,包括PHP编译缓存和PHP数据缓存两种。PHP缓存,这种运行模式的优点是程序修改很方便,但是运行效率却很低下。PHP编译缓存针对这种情况做改进处理,使得PHP语言只要运行一次,就可以把程序的编译结果缓存起来。这样,接下来的每次运行都不需要再次编译了,这大大提高PHP运行速度。

PHP 缓存介绍

什么是缓存

    数据交换的缓冲区(称作Cache)
    临时文件交换区

缓存作用

    减少网络延迟,加快页面打开速度
    减少数据查询次数,降低数据库压力
    降低系统负荷,极大的提升系统性能

常用缓存类型

    文件缓存:使用 PHP 文件操作函数,把数据缓存到服务器磁盘文件中
    内存缓存:Redis、Memcached、MongoDB
    Opcode缓存:PHP 是一种解释型脚本语言,在 PHP 执行过程中,虚拟机会把 PHP 代码翻译成中间语言,这种中间语言就叫 Opcode,然后虚拟机再把 Opcode 顺序执行。把 PHP 代码对应的 Opcode缓存到内存中,加速 PHP 执行,减少了代码翻译成中间语言这一步操作。


文件缓存内存缓存Opcode缓存
存储介质磁盘文件内存内存
不足IO操作慢、文件锁的存在占内存、不持久部署代码刷新慢
应用举例新闻数据、城市区域会员、商品、SessionOpcodeCache(代码加速)

PHP 常用内存缓存介绍

    PHP是一种脚本语言,脚本执行结束之后,所有的变量全部释放掉,本身没有能力将数据常驻内存。
    PHP借助于内存服务器将缓存数据储存在服务器内存。
    优点:读写速度快、跨服务器存储(例如在做多服务器集群的时候,可以将 Session 存储于内存缓存服务器中)、易于解决主从同步问题,并发问题。
    不足:占用了内存空间、缓存数据有大小限制、数据不易持久化存储。(但是内存缓存带给我们的方便足够可以忽略他的不足)
    常用内存缓存:Memcached、Redis、MongoDB


MemcachedRedisMongoDB
储存数据类型stringstring, list, hash, setbson 丰富查询方式
数据储存位置内存内存 + 硬盘内存 + 硬盘
持久化最长30天RDB 文件快照,AOF(记录写操作)持久化journal持久化
使用场景Session 商品缓存(缓存 < 1MB)缓存、队列日志、区域信息、评论

php opcode缓存

PHP Opcode原理

Opcode是一种PHP脚本编译后的中间语言,就像Java的ByteCode,或者.NET的MSL,举个例子,比如你写下了如下的PHP代码

<?php
  echo "Hello World";
  $a = 1 + 1;
  echo $a;
?>

PHP执行这段代码会经过如下4个步骤(确切的来说,应该是PHP的语言引擎Zend)

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

 学过编译原理的同学都应该对编译原理中的词法分析步骤有所了解,Lex就是一个词法分析的依据表。 Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l(Lex文件),来输入的 PHP代码进行词法分析,从而得到一个一个的&ldquo;词&rdquo;,PHP4.2开始提供了一个函数叫token_get_all,这个函数就可以讲一段PHP代码 Scanning成Tokens;如果用这个函数处理前面的PHP代码,将会得到如下结果:

Array
(
   [0] => Array
       (
          [0] => 367
          [1] => Array
       (
           [0] => 316
           [1] => echo
       )
   [2] => Array
       (
           [0] => 370
           [1] =>
       )
   [3] => Array
       (
           [0] => 315
           [1] => "Hello World"
       )
   [4] => ;
   [5] => Array
       (
           [0] => 370
           [1] =>
       )
   [6] => =
   [7] => Array
       (
           [0] => 370
           [1] =>
       )
   [8] => Array
       (
           [0] => 305
           [1] => 1
       )
   [9] => Array
       (
           [0] => 370
           [1] =>
       )
   [10] => +
   [11] => Array
       (
           [0] => 370
           [1] =>
       )
   [12] => Array
       (
           [0] => 305
           [1] => 1
       )
   [13] => ;
   [14] => Array
       (
           [0] => 370
           [1] =>
       )
   [15] => Array
       (
           [0] => 316
           [1] => echo
       )
   [16] => Array
       (
           [0] => 370
           [1] =>
       )
   [17] => ;
)

分析这个返回结果我们可以发现,源码中的字符串,字符,空格,都会原样返回。每个源代码中的字符,都会出现在相应的顺序处。而,其他的比如标签,操作符,语句,都会被转换成一个包含俩部分的Array: Token ID (也就是在Zend内部的改Token的对应码,比如,T_ECHO,T_STRING),和源码中的原来的内容。
接下来,就是Parsing阶段了,Parsing首先会丢弃Tokens Array中的多于的空格,然后将剩余的Tokens转换成一个一个的简单的表达式

1.echo a constant string
2.add two numbers together
3.store the result of the prior expression to a variable
4.echo a variable

然后就改Compilation阶段了,它会把Tokens编译成一个个op_array, 每个op_arrayd包含如下5个部分:

1.Opcode数字的标识,指明了每个op_array的操作类型,比如add , echo
2.结果 存放Opcode结果
3.操作数1 给Opcode的操作数
4.操作数2
5.扩展值1个整形用来区别被重载的操作符

比如,我们的PHP代码会被Parsing成:

* ZEND_ECHO 'Hello World'
* ZEND_ADD ~0 1 1
* ZEND_ASSIGN !0 ~0
* ZEND_ECHO !0

 php文件缓存

因为如果程序访问数据库时数据量较大,执行起来会比较慢。而且每一次刷新页面都会访问依稀数据库,然后再把数据显示在页面上。 设置缓存也有一个缺点,那就是缓存时间要设置好,如果缓存时间较长,那么数据库数据变化时,不能及时的在页面上显示。例如缓存不能用在秒杀商品,或者出售商品上面,因为数量不能及时的更新。

<?php
//缓存文件一般都放在caches文件夹里面。

//定义一个该页面的缓存文件路径,也就是该缓存的文件放在哪个文件夹里面。

$filename = "../cache/testhuancun.html";//定义了一个缓存的文件,文件名为testhuancun.html,位置在../cache文件夹里面。

//设置一个缓存时间
$time = 10;//代表缓存时间设置为10s.

//判断缓存文件是否存在
if(!file_exists($filename) || filemtime($filename)+$time<time())
//判断文件是否存在,如果不存在,执行{}里面的代码。还要判断缓存时间有没有过,如果已经过了,要重新读取数据库更新缓存。
//filemtime($filename)读取文件最后被修改的时间,time()取当前时间戳

{
   //开启内存缓存
   ob_start();//这里开启内存缓存以后,下面要输出的内容全部放在内存缓存里面。

   include("../init.inc.php");
   include("../DBDA.php");
   $db = new DBDA();
   $sql = "select * from nation";
   $attr = $db->Query($sql);
   $smarty->assign("nation",$attr);
   $smarty->display("test.html");

   //把内存里面的内容读出来
   $nr = ob_get_contents();//ob就是代表的缓存,读取的内容就是整个静态页面。

   //将读到的内容存放到缓存文件
   file_put_contents($filename,$nr);//get是取出内容,put是往里放内容,把内存缓存的文件存到¥filename里面。


   //清除内存缓存
   ob_flush();//把内存缓存的内容清除掉,不让它们继续留在缓存内存里面,但是需要缓存的内容已经放在了$filename里面了,已经保存下来了。

   echo "#############################";//输出内容加上一句话,观察输出内容是输出的缓存页面还是加载数据库的页面。这句话放在了ob_flush后面,不会被清除掉。
}
else//如果缓存文件存在,直接将缓存文件拿到页面显示。
{
   include($filename);//将缓存的页面加载到显示页面中
}
标签:php,缓存
0
投稿

猜你喜欢

  • 如何创建一个对索引服务器进行查询的ASP页面?

    2009-11-14 20:54:00
  • 《细节决定交互设计的成败》

    2009-06-02 11:23:00
  • 表单制作方式大比拼

    2008-10-09 11:32:00
  • 两个asp函数实现javascript的escape函数和unescape函数功能

    2009-02-04 15:47:00
  • ASP和Javascript中取整函数的应用

    2009-06-07 18:38:00
  • 创建数据表/创建列的一些asp函数

    2008-06-24 12:21:00
  • 从长尾理论和二八定律的比较去看用户体验

    2009-07-22 19:11:00
  • SQL SERVER数据操作类代码

    2012-07-11 16:16:12
  • 多个函数验证同一表单方法

    2007-10-06 22:55:00
  • 用画为5.12地震受灾同胞们祈福

    2008-05-20 12:08:00
  • SQL Server数据库占用过多内存的解决方法

    2009-10-23 14:02:00
  • Access数据库中“所有记录中均未找到搜索关键字”的解决方法

    2011-04-14 10:31:00
  • 有用的:nth-child秘方

    2011-07-01 12:56:11
  • 创意设计:字母趣味组合

    2008-01-26 18:50:00
  • css清除浮动“clear:both;”的应用

    2008-03-17 12:54:00
  • 如何禁止搜索引擎收录你的网站

    2008-10-20 12:57:00
  • CSS背景属性5个应用实例

    2009-09-13 20:54:00
  • asp截取字符串的两种应用

    2009-08-19 17:11:00
  • js实现用div层模拟的小窗口

    2007-12-02 15:01:00
  • asp如何制作一个股票滚屏显示面板?

    2010-07-07 12:27:00
  • asp之家 网络编程 m.aspxhome.com