OPCache使用示例

OPcache 有什么用?

OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销。

OPcache如何开启?

参考手册:http://php.net/manual/zh/opcache.installation.php

OPcache相关设置?(本文主要针对windows上的配置)

关于配置的说明和更多的配置项参考:http://php.net/manual/zh/opcache.configuration.php

OPcache使用(OPcache函数)

1、 opcache_get_configuration ()   获取缓存的配置信息

opcache_get_status ()            获取缓存的状态信息


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

<?php

    echo ‘<pre>‘;

    //  获取缓存的配置信息

    var_dump(opcache_get_configuration());

    echo ‘<hr/>‘;

    //  获取缓存的状态信息

    var_dump(opcache_get_status());

    echo ‘</pre>‘;

    /**

     * opcache_get_configuration和opcache_get_status返回的都是一组有关缓存配置信息

     * 类似于上面的输出

array(3) {

  ["directives"]=>

  array(24) {

    ["opcache.enable"]=>

    bool(true)

    ["opcache.enable_cli"]=>

    bool(true)

    ["opcache.use_cwd"]=>

    bool(true)

    ["opcache.validate_timestamps"]=>

    bool(true)

    ["opcache.inherited_hack"]=>

    bool(true)

    ["opcache.dups_fix"]=>

    bool(false)

    ["opcache.revalidate_path"]=>

    bool(false)

    ["opcache.log_verbosity_level"]=>

    int(1)

    ["opcache.memory_consumption"]=>

    int(134217728)

    ["opcache.max_accelerated_files"]=>

    int(4000)

    ["opcache.max_wasted_percentage"]=>

    float(0.05)

    ["opcache.consistency_checks"]=>

    int(0)

    ["opcache.force_restart_timeout"]=>

    int(180)

    ["opcache.revalidate_freq"]=>

    int(60)

    ["opcache.preferred_memory_model"]=>

    string(0) ""

    ["opcache.blacklist_filename"]=>

    string(0) ""

    ["opcache.max_file_size"]=>

    int(0)

    ["opcache.error_log"]=>

    string(0) ""

    ["opcache.protect_memory"]=>

    bool(false)

    ["opcache.save_comments"]=>

    bool(true)

    ["opcache.load_comments"]=>

    bool(true)

    ["opcache.fast_shutdown"]=>

    bool(true)

    ["opcache.enable_file_override"]=>

    bool(false)

    ["opcache.optimization_level"]=>

    int(2147483647)

  }

  ["version"]=>

  array(2) {

    ["version"]=>

    string(5) "7.0.3"

    ["opcache_product_name"]=>

    string(12) "Zend OPcache"

  }

  ["blacklist"]=>

  array(0) {

  }

}

array(7) {

  ["opcache_enabled"]=>

  bool(true)

  ["cache_full"]=>

  bool(false)

  ["restart_pending"]=>

  bool(false)

  ["restart_in_progress"]=>

  bool(false)

  ["memory_usage"]=>

  array(4) {

    ["used_memory"]=>

    int(231368)

    ["free_memory"]=>

    int(133986360)

    ["wasted_memory"]=>

    int(0)

    ["current_wasted_percentage"]=>

    float(0)

  }

  ["opcache_statistics"]=>

  array(13) {

    ["num_cached_scripts"]=>

    int(2)

    ["num_cached_keys"]=>

    int(4)

    ["max_cached_keys"]=>

    int(7963)

    ["hits"]=>

    int(0)

    ["start_time"]=>

    int(1429153705)

    ["last_restart_time"]=>

    int(1429161635)

    ["oom_restarts"]=>

    int(0)

    ["hash_restarts"]=>

    int(0)

    ["manual_restarts"]=>

    int(81)

    ["misses"]=>

    int(2)

    ["blacklist_misses"]=>

    int(0)

    ["blacklist_miss_ratio"]=>

    float(0)

    ["opcache_hit_rate"]=>

    float(0)

  }

  ["scripts"]=>

  array(2) {

    ["D:\WWW\php-code\opcache\optest.php"]=>

    array(6) {

      ["full_path"]=>

      string(34) "D:\WWW\php-code\opcache\optest.php"

      ["hits"]=>

      int(0)

      ["memory_consumption"]=>

      int(4656)

      ["last_used"]=>

      string(24) "Thu Apr 16 13:20:35 2015"

      ["last_used_timestamp"]=>

      int(1429161635)

      ["timestamp"]=>

      int(1429161630)

    }

    ["D:\WWW\php-code\opcache\opcache_config.php"]=>

    array(6) {

      ["full_path"]=>

      string(42) "D:\WWW\php-code\opcache\opcache_config.php"

      ["hits"]=>

      int(0)

      ["memory_consumption"]=>

      int(2080)

      ["last_used"]=>

      string(24) "Thu Apr 16 14:28:32 2015"

      ["last_used_timestamp"]=>

      int(1429165712)

      ["timestamp"]=>

      int(1429150438)

    }

  }

}

     */

2、下面我们将进行一些练习示例,注意所有的这一切都需要你确定你已经开启了php的OPcache扩展

去掉php.ini文件中的OPcache前面的分号

完成后重启Apache服务。

现在你将会发现:当我们像平时一样修改php代码以后刷新页面,页面并不会立即显示出我们的变化,好了来段代码说明:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?php

    $stime = microtime();

    try{

            // 这里我们简单的写了一个PDO连接数据库的测试程序

            $dsn = "mysql:host=localhost;dbname=test";

            $pdo = new PDO($dsn, ‘root‘, ‘root‘);

            $sql = "SELECT * FROM account";

            $stmt = $pdo->prepare($sql);

            $stmt->execute();

            // 假设第一次我们只输出了有多少行

            echo $stmt->rowCount();

            

    }catch(PDOExecption $e){

        $e->getMessage();

    }

这里显示有 6 条数据,

如果我们此时想打印这 6 条数据,我们像平时那样,简单修改一下代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

    $stime = microtime();

    try{

            // 这里我们简单的写了一个PDO连接数据库的测试程序

            $dsn = "mysql:host=localhost;dbname=test";

            $pdo = new PDO($dsn, ‘root‘, ‘root‘);

            $sql = "SELECT * FROM account";

            $stmt = $pdo->prepare($sql);

            $stmt->execute();

            // 假设第一次我们只输出了有多少行

            echo $stmt->rowCount();

            echo ‘<hr/>‘;

            // 我们想要打印查询出的所有数据

            print_r($stmt->fetchAll());

    }catch(PDOExecption $e){

        $e->getMessage();

    }

我们现在刷新页面发现,

咦? 怎么没有变化,难道是我们写错了吗? 如果你确定自己的代码没有问题,那么问题来了?这是为什么?是Apache疯了还是php疯了,还是我自己疯了?

其实如果你对自己的代码有信心也有耐心,多刷新几次,就会发现,结果出来了

好奇怪?有木有,其实不是这样了,由于我们上面修改php.ini文件已经开启OPcache,当我们第一次运行这个脚本的时候,php会检查->翻译->运行 我们写的这个脚本,和以前是一样的,但是我们开启了OPcache,这次php会将翻译好的php中间代码:字节码opcode加载到内存中,当再次修改我们的脚本运行时,其实运行的是内存中的php中间代码opcode,我们修改过的脚本并没有运行

那为什么过一会,又显示正确了呢?

还是我们上面 OPcache 的设置 

看看解释:


1

2

opcache.revalidate_freq integer

检查脚本时间戳是否有更新的周期,以秒为单位。 设置为 0 会导致针对每个请求, OPcache 都会检查脚本更新。

所以就是每60秒php会检查我们的脚本是否被修改过,如果修改过那就重新执行正常的那一套:检查->翻译->运行,然后把中间代码加载到内存中,

所以在上面 我们的修改不会跟往常一样刷新页面就行,需要等待一会。这样是不是对缓存很有感受啊:我们修改了文件,却跟没有修改一样 ,页面没有显示任何变化 0.0 !

3、opcache_reset()   重置字节码缓存的内容

对于我们上面出现的这种情况,如果我们不想每次都等待60秒,我们就可以使用这个方法,这个方法的定义是:在调用 opcache_reset() 之后,所有的脚本将会重新载入并且在下次被点击的时候重新解析。

注意一旦调用这个方法,所有的脚本都会被重新解析,然后再次载入到内存,记住是所有脚本,如果我们只是针对某个脚本的话,我们可以考虑使用:opcache_invalidate — 废除脚本缓存 (下面再说这个)

下面我们新建两个文件:opecho.php和opreset.php,简单的几行代码做个示例


1

2

3

4

5

6

7

8

9

<?php

    /*

     * filename: opecho.php

     * author  : wangxb

     * create  : 2015_04_17 02:44:16

     * update  : @update

     */

echo "这是第一次修改,这个脚本会和以前一样去解释执行,然后将翻译好的中间代码opcode载入到内存中,<br>当我们在一分钟之内再次修改文件输出是没有变化的";

 

然后假设我们此时,又想echo一些内容


1

2

3

4

5

6

7

8

9

10

11

12

13

<?php

    /*

     * filename: opecho.php

     * author  : wangxb

     * create  : 2015_04_17 02:44:16

     * update  : @update

     */

echo "这是第一次修改,这个脚本会和以前一样去解释执行,然后将翻译好的中间代码opcode载入到内存中,<br>当我们在一分钟之内再次修改文件输出是没有变化的";

// 假设此时我们想在输出一些内容

echo "<hr/>";

echo "这是第二次输出";

我们发现,修改代码后没有变化

然后我们执行 opreset.php

opreset.php


1

2

3

4

5

6

7

8

9

<?php

    /*

     * filename: opreset.php

     * author  : wangxb

     * create  : 2015_04_17 02:44:25

     * update  : @update

     */

// 当我们在调用这个文件中 opcache_reset() 方法之后,我们不用等待 60秒,此时 所有脚本会重新走一次php标准的流程,

也就相当于我们修改后的脚本重新解释执行 然后将修改后的脚本的中间代码 字节码 opcode加载到内存中,我们就可以看到我们的修改效果了

    echo opcache_reset() ? ‘成功重置缓存内容‘ : ‘重置失败‘;

刷新我们刚才的页面

修改出现了,如果你觉得你在60内完不成这么多操作,无法出现按我说的这样的情景,可以把 opcache.revalidate_freq 这个参数设置大一些 比如 180 秒,这样的话 会每隔三分钟才去坚持一次文件是否更新过

4、opcache_invalidate ()

现在我们再新建一个opinvalidate.php 文件,再新建一个opecho1.php文件,利用我们上面的opecho.php文件,这次我们只想重新解释执行opecho1.php中的修改,


1

2

3

4

5

6

7

8

<?php

    /*

     * filename: opecho1.php

     * author  : wangxb

     * create  : 2015_04_17 10:44:20

     * update  : @update

     */

    echo ‘我们将使用php中的opcache_invalidate()方法,让这个文件的字节码opcode手动失效‘;

此时我们执行文件页面

此时我们同时修改opecho.php和opecho1.php这两个文件


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?php

    /*

     * filename: opecho.php

     * author  : wangxb

     * create  : 2015_04_17 02:44:16

     * update  : @update

     */

echo "这是第一次修改,这个脚本会和以前一样去解释执行,然后将翻译好的中间代码opcode载入到内存中,<br>当我们在一分钟之内再次修改文件输出是没有变化的";

// 假设此时我们想在输出一些内容

echo "<hr/>";

echo "这是第二次输出";

echo ‘<hr/>修改了opecho1.php文件‘;


1

2

3

4

5

6

7

8

9

10

<?php

    /*

     * filename: opecho1.php

     * author  : wangxb

     * create  : 2015_04_17 10:44:20

     * update  : @update

     */

    echo ‘我们将使用php中的opcache_invalidate()方法,让这个文件的字节码opcode手动失效‘;

    echo ‘<hr/>修改了opecho1.php文件‘;

然后刷新页面,页面没有变化:

当我们执行opinvalidate.php


1

2

3

4

5

<?php

    // opcache_invalidate() 方法中有两个参数:

    // args: 1、 缓存需要被作废对应的脚本路径

    //       2、 布尔型,true表示 强制作废, false或者缺省值,表示文件更新后才失效

    echo opcache_invalidate(‘./opecho1.php‘, TRUE) ? ‘操作成功‘ : ‘操作失败‘;

我们就会看到:刷新 opecho1.php 页面

我们的修改出现了,再来看看opecho.php页面

没有变化,明白?  我们运行opinvalidate.php页面时,opecho1.php 脚本在缓存中的opcode被废弃了,php会重新执行一次opecho1.php这个脚本,所以我们看到了 我们的修改

5、opcache_compile_file() 方法:无需运行,即可编译并缓存 PHP 脚本

我们新建两个脚本:opcompile.php和compileScript.php,我们在opcompile.php中执行OPcache_compile_file方法缓存compileScript.php脚本


1

2

3

4

5

6

7

8

9

10

11

<?php

    /*

     * filename: opcomplie.php

     * author  : wangxb

     * create  : 2015_04_17 11:53:30

     * update  : @update

     */

    // opcache_compile_file() 方法要求传入待缓存文件的路径,此时不需要运行这个带缓存文件,只需要执行这个方法即可在内存中缓存

    echo opcache_compile_file(‘./compileScript.php‘) ? ‘脚本成功缓存‘ : ‘脚本缓存失败‘;


1

2

3

4

5

6

7

8

9

<?php

    /*

     * filename: compileScript.php

     * author  : wangxb

     * create  : 2015_04_17 12:44:16

     * update  : @update

     */

    echo ‘这是脚本compileScript.php‘;

现在执行 compile.php文件,让他去把compileScript.php脚本加入到缓存中

然后我们修改:compileScript.php


1

2

3

4

5

6

7

8

9

10

11

<?php

    /*

     * filename: compileScript.php

     * author  : wangxb

     * create  : 2015_04_17 12:44:16

     * update  : @update

     */

    echo ‘这是脚本compileScript.php‘;

    echo ‘我们第一次修改compileScript.php文件‘;

现在来在浏览器中看看这个脚本:

没有变化,那是因为,这次运行的时候,执行的是我们上面执行compile.php文件时在内存中生成的第一次的compileScript.php的中间代码

6、opcache_is_script_cached() 

这个方法看名字估计都能猜出他是什么意思了:检查一个脚本是否在OPcache缓存中

我们也来一个示例:


1

2

3

4

5

6

7

8

9

10

<?php

    /*

     * filename: opisscriptcache.php

     * author  : wangxb

     * create  : 2015_04_17 13:14:16

     * update  : @update

     */

    //  我们就以前面已经在加载到内存中的opecho.php文件作为测试对象

    echo opcache_is_script_cached(‘./opecho.php‘) ? ‘opecho.php脚本中间代码已经缓存‘ : ‘opecho.php没有缓存中间代码opcode在内存中‘;

很不幸,出了一个很严重的错误,

没有这个方法,难道是我们错了吗?

其实不是了,是因为这个方法要求:

看看我们的PHPinfo

所以用不了,其他的为什么都好着? 其他的方法要求进步都是v7.0.0、v7.0.2  我们这个满足,所以其他方法都可以使用,既然这样,这个方法也就这么说说算了,很简单的一个方法,平时也就是测试使用

切记:最后如果你测试完了,还是应该关闭OPcache,这样才不至于被OPcache捣乱我们平时的开发工作

  结语

好了,关于php缓存 OPcache的使用就介绍到这里,php还有一个扩张APC也是针对缓存的,我们下一篇再做说明,只用缓存来说,这个面就很大了,不光是这里说的php的缓存,数据库数据缓存、页面缓存等等。所以目前打算先把php中间OPcache层面的缓存弄清楚

如果你不知道什么是opcode字节码、中间代码,给你推荐一篇博客:http://blog.linuxeye.com/361.html

OK、就先这样吧,这段时间被换工作的事情搞得有点烦,上周面试了一家公司,不是专门做开发的公司,估计是那种做做页面一两个人维护的简单网站或者写一些简单的微信开发什么的,其实我不是开不起这样的公司,这家公司给我还不错的待遇,可是我是过不了心里那一道坎:幻想能找到一个技术氛围好的开发公司,自己能够见识到更多、更深、更广。自己也能在技术上有更大的提高,可是心里又告诉自己,难道一辈子要当个程序员吗?应该为以后想想,不一定要技术成长,工资待遇可以就行了。可是自己还是过不了心里那颗技术的梦,还是放不下在技术道路上狂奔的想法。哎、纠结,只能写写博客缓解一下这么纠结的心情了,让自己静静

上面的代码在本人的GitHub上: https://github.com/wxb/php-code/tree/master/opcache

来自为知笔记(Wiz)

时间: 2024-08-30 00:06:27

OPCache使用示例的相关文章

PHP 缓存插件之 Zend Opcache ( 取代 APC )

简介: Zend Opcache .APC 这都是 PHP 代码加速器,将 PHP 源代码的编译结果缓存起来,再次调用时对比时间标记,如果没有改变则使用缓存数据,免去再次解析代码的开销. APC 止步于 PHP 5.4 ,Zend Opcache 从 PHP 5.5 开始集成,取代 APC . 一.安装 Zend Opcache 1.源码编译 PHP 时,加入 --enable-opcache 即可开启该扩展,之后稍做配置即可 2.手动添加 Zend Opcache 扩展. shell > cd

php开启opcache

OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销. 一.php.ini配置opchche示例 [opcache] zend_extension=opcache.so ; 开关打开 opcache.enable=1opcache.enable_cli=1;共享内存大小, 酌情而定,单位 megabytes opcache.memory_consumption=256      ;inte

现代 PHP 新特性 —— Zend Opcache (转)

转自:https://laravelacademy.org/post/4396.html 1.概述 字节码缓存不是PHP的新特性,有很多独立的扩展可以实现,比如APC.eAccelerator和Xache等,但是截至目前这些扩展都没有集成到PHP内核,从PHP 5.5.0开始,PHP内置了字节码缓存功能,名为Zend Opcache. 开始之前,我们先来看看什么是字节码缓存,以及字节码缓存的作用是什么. 众所周知,PHP是解释型语言,构建在Zend 虚拟机之上,PHP解释器在执行PHP脚本时会解

pfsense Web服务器负载平衡配置示例

在pfsense的网关和服务器中有两种类型的负载平衡功能.网关负载平衡可以通过多个WAN连接分发Internet绑定的流量.服务器负载平衡管理传入流量,因此它利用多个内部服务器进行负载分配和冗余,服务器负载平衡允许流量在多个内部服务器之间分配,它最常用于Web服务器和SMTP服务器.下面我们就以实例来介绍服务器负载平衡的设置. 下面介绍如何通过pfsense2.32配置Web服务器的负载平衡. 网络环境 服务器负载平衡示例网络环境 上图为示例网络环境.它由单个防火墙组成,使用其WAN IP地址池

docker深入2-API示例

2017/9/18 一.目的 演示 http API 使用的方式 注1:本次实例是在 docker swarm mode 下使用的,目的是:更新指定服务的镜像. 注2:要在 swarm manager node 上执行. docker 的 API 文档是自动生成的,没有太多有用的示例可用. [版本] ~]# docker version Client:  Version:      17.06.0-ce  API version:  1.30  Go version:   go1.8.3  Gi

Storm入门(四)WordCount示例

Storm API文档网址如下: http://storm.apache.org/releases/current/javadocs/index.html 一.关联代码 使用maven,代码如下. pom.xml  和Storm入门(三)HelloWorld示例相同 RandomSentenceSpout.java /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor lice

java第15章示例代码

import java.util.Scanner; /** * * @author asus第15章示例代码1 全桂群2017.4.9 * */public class Registter { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); String uname, pw

算法之冒泡排序(Java示例)

冒泡排序(英语:Bubble Sort) 是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 动画示意 实现示例 Java 1 public class BubbleSortExample { 2 3 static void bubbleSort(int[] arr){ 4 int len =

Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3534050.html Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可