PHP APC在CLI模式下的应用

20

在 PHP CLI 模式下运行时,APC 模块是否支持代码优化?例如,当我使用 php -f <file> 命令运行一个文件时,该文件是否会在执行之前通过 APC 进行优化?假设在配置文件中设置了 APC 加载。另外,使用 require_once 包含的脚本是否也会被优化?

我知道在 fastcgi 模式下运行时优化效果很好,但我想知道它是否也适用于 CLI 模式。

apc_* 函数可以正常工作,但我关心的主要是代码优化。

愉快的一天, Matic

4个回答

29
apc.enable_cli 的文档控制 APC 是否在 CLI 模式下激活,其中写到:

主要用于测试和调试。 设置此项将启用 PHP CLI 版本中的 APC。 在正常情况下,在每个 CLI 请求中创建、填充和销毁 APC 缓存并不理想, 但对于各种测试场景,能够轻松地为 PHP CLI 版本启用 APC 是有用的。

或许 APC 会把 opcode 存储在内存中,但随着 PHP 执行结束,这段内存也将丢失:它不会在脚本执行之间保留。

因此,在 CLI 模式下使用 opcode 缓存是无用的:它不会优化任何东西,因为每次启动 PHP 可执行文件时,PHP 仍然需要重新编译源代码为 opcode。


实际上,APC 并没有 "优化" :执行 PHP 脚本的标准方式如下:

  • 读取文件,将其编译为 opcode
  • 执行 opcode

APC 所做的就是将 opcode 存储在内存中,因此执行 PHP 脚本变成了:

  • 从内存中读取 opcode (比编译源代码快得多)
  • 执行 opcode

但这意味着你必须有一些地方来存储这些 opcode。当 PHP 作为 Apache 模块运行时,Apache 负责该内存段的持久化...当 PHP 从 CLI 运行时,没有任何东西可以保留内存段,因此在 PHP 执行结束时它被销毁。
(我不知道它的确切工作原理,但至少原理上是这样的,即使我的话不太 "技术性" ^^ )


或者,如果您所说的“优化”并非指操作码缓存,而是指配置指令apc.optimization的话,那么这个指令在APC 3.0.13中已经被删除了。


来自PHP文档: APC是一个免费、开放和强大的框架,用于缓存和优化PHP中间代码。我想知道一下关于中间代码优化的情况。我打算只执行一次CLI脚本,然后它将在几天内运行,在循环中执行一些代码。所以,APC并没有真正加速执行本身,只是缩短了开始执行的时间? - Matic
http://pecl.php.net/package-info.php?package=APC&version=3.0.13 上说“废弃并删除apc优化器”;我从未听说过APC(至少在最近的版本中)做过任何像你在编写C程序时可以想到的“优化”类型。而且我不认为它会减少启动执行所需的时间,因为PHP将被编译为opcode(正是在这一部分中,APC允许巨大的收益……当它可以在脚本执行之间保留这些opcode在内存中——我不认为它可以在CLI中实现)。 - Pascal MARTIN
1
只是为了明确,即使在CLI模式下使用APC仍然非常有用,可以缓存用户生成的对象。在我正在处理的脚本中,我们使用apc_store()和apc_fetch()来利用APC的用户对象缓存,在长时间运行的cron作业中。 - rinogo

7
如果您有基于环境生成任何配置的CLI代码,那么CLI代码会认为APC未启用。例如,通过CLI生成Symfony的DI容器时,它会告诉Doctrine不要使用APC(详情请参见:此处)。
另外,我没有测试过,但是有可能在pcntl_fork()之后包含的文件的脚本速度上,APC可以提高速度。编辑:我在这里问了关于APC和pcntl_fork()的问题。
为了完整起见,在Ubuntu上启用CLI中的APC:
echo 'apc.enable_cli = 1' > /etc/php5/cli/conf.d/enable-apc-cli.ini

3

在CLI模式下使用的另一个原因是:一些脚本可以将其用作缓存


3

在CLI模式下使用APC是有好处的: 单元测试:我想使用尽可能接近后续生产环境的环境进行单元测试。Zend Framework具有内部缓存解决方案,该解决方案可以使用APC的变量缓存作为存储后端 - 我想使用这个。


我认为在这种情况下,您可能需要查看另一个用于单元测试的后端。好在这在Zend_Cache中是可插拔的。 - Till
我知道,但是那些后端并不完全表现相同。因此,我想使用相同的后端进行单元测试。 - Laph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接