性能

Symfony运行速度是还可以,嗯……如果你还需要加速,有许多方法可以让Symfony跑得更快。这章就是来告诉你怎么做的。

使用二进制代码缓存(比如APC)

最好又最简单的方法,你应该使用二进制代码缓存。二进制代码缓存的原理是直接缓存PHP文件编译之后的中间代码。目前有各种 byte code caches ,其中有些还是开源的。从PHP 5.5开始, PHP自带 OPcache 。更早的PHP版本用得最多的应该是 APC

使用二进制代码缓存不会带来任何副作用,而且Symfony在这样的运行环境中跑得也很好。

更多优化

二进制缓存一般来说会监控文件是否有变化。如果发现文件变了,就会被重新编译一遍。这很方便,不过很显然会多消耗运算资源。

基于这个原因,一些二进制代码缓存可以关闭文件检查。如果关闭检查,就应该让服务器管理来确定源文件是否有变化,否则即是提更新了源文件也不会看到任何变化。

举个栗子:关闭APC的文件检查,仅需添加 apc.stat=0php.ini 即可。

使用Composer类映射表功能

默认情况下,Symfony标准版使用了Composer的自动加载工具也就是 autoload.php 文件。此自动加载工具很易于使用,他将帮你自动地在注册过的目录中找到任何新加的类。

遗憾的是,这样对计算资源有所消耗,因为加载器要不断查找每一个注册的命名空间去找某个文件,然后通过 file_exists 来检查文件直到找到为止。

最简单的优化方式就是告诉Composer创建一个“类映射表” (比如一个很大的数组,存有所有的类的存放地址)。可以通过一行命令就搞定,并且应该是你部署项目中的其中一步:

$ composer dump-autoload --optimize

在内部,这将创建一个很大的类映射数组到 vendor/composer/autoload_classmap.php

将类载入器缓存到APC

另外一个解决办法是在类被找到之后,缓存每一个类的地址。Symfony包含了一个叫 ApcClassLoader 的类,就是用来干这个的。要使用这个类,只用在你的前端控制器里改一下。如果你安装的Symfony标准版。这个代码应该已经有了,只不过被注释掉了而已:

// app.php
// ...

$loader = require_once __DIR__.'/../app/bootstrap.php.cache';

// Use APC for autoloading to improve performance
// Change 'sf2' by the prefix you want in order
// to prevent key conflict with another application
/*
$loader = new ApcClassLoader('sf2', $loader);
$loader->register(true);
*/

// ...

请看 Cache a Class Loader 查阅更多。

注解

当使用APC自动加载器的时候,如果你添加新的类,他们会自动被发现,其他的一如既往(比如说连运行缓存清理都没有必要)。但是如果你改变了某个命名空间或者前缀,你还是需要清理APC的缓存的,否则自动加载器依然会去老位置去查找文件。

使用引导文件

为了保证灵活性以及代码复用性,Symfony包含了大量类以及第三方的组件。但如果每一个请求都需要把他们全部重新载入一次,肯定会占用一些没必要的计算资源。为了做些优化,Symfony提供了一个可以生成 bootstrap file 的脚本,可以将许多类的定义并接到一个文件中。只要包含了这个文件,就不用再去包含其他文件了,这种方式可以减少许多不必要的磁盘读写开销。

如果你使用的是Symfony标准版,那你应该已经在用引导文件了,你可以通过打开你的前端控制器(一般来说是 app.php )然后检查是否包含以下代码的方式来确认:

require_once __DIR__.'/../app/bootstrap.php.cache';

注意使用引导文件有两个不好的地方:

  • 只要源代码有一点变化,此文件就需要重新被生成(比如更新了Symfony的源代码或者第三方库);

  • 在调试的时候,只能把断点设置在引导文件里。

如果你用的是Symfony标准版,引导文件会在每一次执行 composer install 命令跑完之后都会被更新。

引导文件和二进制代码缓存

即是在打开二进制缓存的情况之下,使用引导文件也能使性能有所提升,因为需要监控的文件变少了。当然如果在关闭文件监控的情况下是无差别的。(比如在 apc.stat=0 的时候,没有必要再用启动文件)