当前位置: 首页 > 后端技术 > PHP

【现代PHP专题(13)】ZendOpcache字节码缓存

时间:2023-03-29 22:12:12 PHP

概述字节码缓存并不是PHP的新特性,有很多独立的扩展可以实现,比如APC、eAccelerator和Xache等,但是到目前为止这些扩展还没有集成到PHP核心,从PHP5.5.0开始,PHP内置了一个字节码缓存功能,叫做ZendOpcache。在开始之前,让我们先了解一下什么是字节码缓存以及字节码缓存的作用。众所周知,PHP是一种建立在Zend虚拟机之上的解释型语言。PHP解释器在执行PHP脚本时会解析PHP脚本代码,将PHP代码编译成一系列的Zend操作码(opcode,由于每个操作码都是一个字节长,所以也叫字节码,字节码可以是Zend虚拟机直接执行),然后执行字节码。每次请求一个PHP文件都是这样,资源消耗很大。如果每一个HTTP请求都要不断地解析、编译和执行PHP脚本,会消耗更多的资源。如果PHP源代码不变,相应的字节码就不会改变。显然,没必要每次都重新生成Opcode。结合Web应用中无处不在的缓存机制,我们可以将第一次生成的Opcode缓存起来,这样第一次直接从缓存中取不是很快吗?下面是启用Opcode缓存前后的流程图:字节码缓存可以存储预编译的PHP字节码,这样下次请求PHP脚本时,PHP解释器就不需要每次都去读取、解析、编译PHP代码了时间,直接从内存中读取预编译的字节码,然后立即执行,可以节省大量时间,大大提高应用程序的性能。启用ZendOpcache注:如果使用Windows开发环境,或者使用brew或apt-get安装PHP,可以跳过编译步骤。默认情况下,ZendOpcache是不启用的,我们需要在编译时使用--enable-opcache来指定ZendOpcache。编译PHP后,需要在php.ini中指定Opcache扩展路径:zend_extension=/path/to/opcache.so一般情况下,PHP编译成功后会显示ZendOpcache扩展路径,但如果不能记住了,可以用下面的命令找到PHP扩展所在的目录:php-ini|grepextensions[info]注意:如果使用Xdebug,需要先在php.ini中加载ZendOpcache,再加载Xdebug。重启后查看phpinfophp-info|grepOpcache配置ZendOpcache启用ZendOpcache后,需要在php.ini中配置ZendOpcache。下面是一个配置示例,供参考:opcache.validate_timestamps=1//生产环境配置为0opcache.revalidate_freq=0//检查脚本时间戳是否有更新时间opcache.memory_consumption=64//Opcache共享内存大小,inMopcache.interned_strings_buffer=16//存放临时字符串的内存大小,以M为单位opcache.max_accelerated_files=4000//Opcache哈希表opcache可以存放的脚本文件数量上限.fast_shutdown=1//使用快速停止重发事件官网配置参考使用ZendOpcacheZendOpcache非常好用,因为它会自动运行,ZendOpcache会自动将预编译的PHP字节码缓存在内存中,如果一个文件的字节码被缓存,相应的字节码将被执行。如果在php.ini中将opcache.validate_timestamps的值设置为0,则需要小心,因为ZendOpcache将无法检测到PHP脚本中的更改。您必须手动清除ZendOPcache缓存的字节码,以允许它检测PHP文件中的更改。该配置在生产环境中适合设置为0,但在开发环境中会造成不便。我们可以在开发环境中这样配置自动验证缓存功能:opcache.enable=1#启用操作码缓存,默认为“1”,如果禁用该选项,代码将不会被优化和缓存。opcache.revalidate_freq=0#检查脚本时间戳是否更新,以秒为单位。设置为0会导致OPcache在每次请求时检查脚本更新。opcache.validate_timestamps=1#如果启用,OPcache将检查脚本是否每秒更新一次,由opcache.revalidate_freq设置。手动清除缓存除了重启php-fpm进程来清除opcache缓存外,手动清除缓存涉及的opcache函数主要有:opcache_reset()和opcache_invalidate()。booleanopcache_reset(void)#这个函数将重置整个字节码缓存。调用opcache_reset()后,所有脚本将在下次命中时重新加载和重新解析。[warning]需要注意的是,PHP运行在PHP-FPM模式下,opcache缓存不能通过php命令清除,只能通过http或者cgi到php-fpm进程清除。