如何在PHP中的请求之间保持对象

时间:2010-05-30 22:40:11

标签: php caching frameworks state persist

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

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

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

感谢。

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

为了证明大的设置时间:如果我使用PHP反射检查哪些对象可用并根据它设置运行时怎么办?进行大量反射通常很慢,但只需要执行一次(并且仅在修改源代码时重新进行评估)。

EDIT2:那似乎是APC。它自动缓存字节码的事实很有用。

3 个答案:

答案 0 :(得分:5)

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

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

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

            $table = @apc_fetch(TABLE_KEY);

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

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

答案 1 :(得分:3)

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

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

要在PHP中实现相同的功能,您可以使用Zend Server。据我所知,这是唯一一个将'编译'并在被告知时使用字节代码的PHP解释器。否则,您需要找到一种方法来存储您希望通过请求保留的数据。正如你所提到的APC是一个非常强大的功能,一个更加分散的是Memcached,当然还有更多持久的形式,如disc& SQL。

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

答案 2 :(得分:0)

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

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

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