20

我过去一直在使用 rails、merb、django 和 asp.net mvc 应用程序。他们的共同点(与问题相关)是他们拥有设置框架的代码。这通常意味着创建持续存在的对象和状态,直到 Web 服务器被回收(例如设置路由,或检查哪些控制器可用等)。

据我所知,PHP 更像是一个 CGI 脚本,每次运行时都会编译为一些字节码,并在发出请求后将其丢弃。当然,您可以拥有会话,以便在来自同一用户的请求之间保留数据,并且正如我所见,有像 APC 这样的扩展,您可以使用它在服务器级别的请求之间保留对象。

我的问题是:如何创建一个像 rails 之类的 PHP 应用程序?我的意思是一个应用程序在第一次请求时设置框架,然后在第二次和以后的请求中使用已经设置的对象。mod_php 中是否有一些内置的缓存设施?(例如,存储已执行 php 应用程序的编译字节码)还是使用 APC 或一些类似的扩展来解决这个问题的唯一方法?你会怎么做?

谢谢。

编辑:替代问题:如果我创建一个大型 PHP 应用程序,它的设置时间很长,但运行时间很短(就像上面提到的框架一样),那么我应该如何“缓存”已经设置的东西(这可能意味着很多东西,除了数据库连接,因为你已经在 PHP 中有持久连接)。

为了证明大型设置时间的合理性:如果我使用 PHP 反射来检查哪些对象可用并据此设置运行时该怎么办。进行大量反思通常很慢,但只需要做一次(并且只有在修改源代码时才重新评估)。

EDIT2:那似乎是APC。很高兴知道它自动缓存字节码的事实。

4

3 回答 3

7

不确定 APC 是否是唯一的解决方案,但 APC 确实可以解决您的所有问题。

首先,您的脚本将使用 APC 编译一次,并且字节码存储在内存中。

如果您的设置需要很长时间,您还可以将其作为用户数据缓存在 APC 中。例如,我一直这样做,

            $table = @apc_fetch(TABLE_KEY);

            if (!$table) {
                    $table = new Table(); // Take long time
                    apc_store(TABLE_KEY, $table);
            }

使用 APC,每个服务器实例只执行一次创建表的任务。

于 2010-05-30T23:03:51.200 回答
4

PHP(以及 ruby​​)是解释性语言。也就是说,他们每次被请求时都会解析文件,我想你可以说被转换为伪字节码。可以说 PHP 更像这样而不是说 RoR 更“明显”,但它们的行为方式相同。

在请求之间持久化数据的特性是服务器的特性,而不是语言本身的特性。例如,您所说的 RoR 路由实际上是缓存的,但它缓存在服务器的本地内存中。它不是为了更快的读取而编译和存储的。服务器(我指的是服务器,我指的是盒子和 Web 服务实例)重新启动此信息已消失。您所说的“设置框架”仍然涉及解析框架中涉及的每个文件。Rails 在请求期间一次又一次地解析每个文件,生产级功能实际上可能会将这些数据缓存在内存中,但在开发中肯定不会。我提到这一点的唯一原因是因为它说明它是服务器的功能而不是语言。

要在 PHP 中实现相同的功能,您可以使用 Zend Server。据我所知,这是唯一一个在被告知时会“编译”并使用字节码的 PHP 解释器。否则,您将需要找到一种方法来存储要在请求中保留的数据。您提到的 APC 是一个非常强大的功能,一个更分布式的功能是 Memcached,当然还有更持久的形式,如磁盘和 sql。

我很想知道你为什么喜欢这个特殊的功能。您是否注意到可以通过这样做“解决”的性能问题?

于 2010-05-30T22:51:00.457 回答
0

我认为您正在做出一些不正确的概括。所有这些框架(例如:Rails)都可以使用不同的配置运行。在某些情况下,会为每个请求创建一个进程。这显然会损害性能,但它表明这些框架不依赖于长时间运行的进程。如果需要,他们可以对每个请求进行设置(重新解析配置文件、创建对象等)。

当然,与 CGI 不同,mod_php(通常使用 PHP 的方式)在 Web 服务器进程中运行。所以我看不出 CakePHP(例如)和 Rails 之间有什么根本不同。

我想也许您正在寻找 Python 的WSGI或 Ruby 的Rack之类的东西,但对于 PHP。这为应用程序指定了一个接口(与语言的运行方式无关)。对于新请求,将创建应用程序对象的新实例。据我所知,这对于 PHP 是不存在的。

于 2010-05-30T22:41:24.373 回答