非常简单的问题,但我实际上无法确定。 PHP如何处理需要/包含已经被APC缓存的文件?我的理解是这个缓存主要是保存PHP编译已经缓存的文件,但是我不清楚它是否也保存了查找/获取文件所需的磁盘命中率。那么,是吗?或者,即使操作码已经被缓存,PHP也会命中磁盘,唯一的区别是它不会再次进行编译过程吗?
我想认为要求/包含神奇地知道文件被缓存并因此直接从内存中获取它,这要归功于APC,但我只是意识到我没有理由认为这是个案,因此我问为什么。
答案 0 :(得分:4)
我认为您在APC手册中解释了有关此主题的问题,但它有点隐藏。你必须阅读configuration部分才能找到它。特别请查看apc.stat配置选项,其中说明了这一点:
...默认为on,强制APC对脚本进行统计(检查) 每个请求以确定它是否已被修改。如果是的话 修改它将重新编译并缓存新版本。如果这个设置 关闭,APC不会检查
...
对于包含/必需的文件,此选项也适用,但请注意 for relative path包含(任何不以/ on开头的路径 Unix)APC必须检查以便唯一地标识文件。如果你 使用绝对路径包括APC可以跳过stat并使用那个绝对值 path作为文件的唯一标识符。
所以看起来APC缓存所需/包含的文件的方式与原始脚本大致相同,如果你通过文件的绝对路径包含/ require 。如果您使用相对路径(许多人都这样做),则需要磁盘命中才能找到完整的文件名。
答案 1 :(得分:1)
实际上,APC 确实为* once变体(include_once,require_once)打开系统调用。 您可以使用strace轻松检查。
这是因为*一次的代码略有不同,调用zend_stream_open 在调用compile_filename(由apc覆盖)之前:
https://github.com/php/php-src/blob/master/Zend/zend_execute.h
错误跟踪器中也有一个未解决的问题: https://bugs.php.net/bug.php?id=59372
答案 2 :(得分:0)
APC覆盖Zend引擎中的函数zend_compile_file,其中负责定位和打开实际文件;由于这个原因,如果文件已经被缓存,它可以在它们发生之前“劫持”磁盘命中。
因此,是的,如果缓存了文件,则会从内存中提供文件。
来源:APC Technotes和Zend Engine源代码,特别是zend_language_scanner.c