簡體   English   中英

如何在PHP中的請求之間保持對象

[英]How to persist objects between requests in PHP

我過去一直在使用rails,merb,django和asp.net mvc應用程序。 他們共同的(與問題相關)是他們擁有建立框架的代碼。 這通常意味着創建持久的對象和狀態,直到Web服務器被回收(如設置路由,或檢查哪些控制器可用等)。

據我所知,PHP更像是一個CGI腳本,每次運行時都會被編譯成一些字節碼,並且在請求之后它被丟棄。 當然,您可以擁有會話,在同一用戶的請求之間保留數據,並且我看到有像APC這樣的擴展,您可以使用它來在服務器級別的請求之間保留對象。

我的問題是:如何創建一個像rails這樣的PHP應用程序? 我的意思是一個應用程序,在第一個請求設置框架,然后在第二個和后來的請求使用已經設置的對象。 mod_php中是否有一些內置的緩存工具? (例如,存儲已執行的php應用程序的已編譯字節碼)或者是使用APC或某些類似擴展來解決此問題的唯一方法? 你會怎么做?

謝謝。

編輯:替代問題:如果我創建一個大的PHP應用程序,它具有非常大的設置時間,但運行時間較短(如上面提到的框架)那么我應該如何“緩存”已經設置的東西(這可能意味着很多東西,除了可能是數據庫連接,因為你已經在PHP中擁有持久連接)。

為了證明大的設置時間:如果我使用PHP反射檢查哪些對象可用並根據它設置運行時該怎么辦? 進行大量反射通常很慢,但只需要執行一次(並且僅在修改源代碼時重新進行評估)。

編輯2:那似乎是APC。 它自動緩存字節碼這一事實很有用。

不確定APC是否是唯一的解決方案,但APC確實解決了您的所有問題。

首先,您的腳本將使用APC編譯一次,字節碼存儲在內存中。

如果您需要花費很長時間進行設置,您還可以將其作為用戶數據緩存在APC中。 例如,我一直這樣做,

            $table = @apc_fetch(TABLE_KEY);

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

使用APC,每個服務器實例只執行一次創建表的任務。

PHP(以及ruby)就是解釋性語言。 也就是說,它們在每次請求時解析文件,我想你可以說它們被轉換為偽字節代碼。 更明顯的是,人們可以說PHP比RoR更像這樣,但它們的行為方式相同。

在請求之間保持數據的特征是服務器的一個特征,而不是語言本身。 例如,您說的RoR路由實際上是緩存的,但它緩存在服務器的本地內存中。 它不是為了更快的讀取而編譯和存儲的。 服務器(以及服務器,我指的是盒子和Web服務實例)重新啟動此信息已經消失。 您所說的“設置框架”仍然涉及解析框架中涉及的EACH文件。 Rails一次又一次地在請求期間解析每個文件,生產級別功能實際上可以將這些數據緩存在內存中,但肯定在開發中它不會。 我提到的唯一原因是因為它說明了它是服務器的一個特性而不是語言。

要在PHP中實現相同的功能,您可以使用Zend Server。 據我所知,這是唯一一個將'編譯'並在被告知時使用字節代碼的PHP解釋器。 否則,您需要找到一種方法來存儲您希望通過請求保留的數據。 你提到的APC是一個非常強大的功能,一個更分散的是Memcached,然后當然還有更多的持久形式,如disc和sql。

我很想知道你為什么喜歡這個特殊的功能。 您是否注意到這樣做會“解決”的性能問題?

我認為你做了一些不正確的概括。 所有這些框架(例如: Rails )都可以使用不同的配置運行。 在某些情況下,會為每個請求創建一個進程。 這顯然會損害性能,但它表明這些框架不依賴於長時間運行的進程。 如果需要,他們可以設置每個請求(重新分配配置文件,創建對象等)。

當然,與CGI不同,mod_php(通常使用PHP的方式)在Web服務器進程內運行。 所以我沒有看到CakePHP(例如)和Rails之間有任何根本的不同。

我想也許你正在尋找類似Python的WSGI或Ruby的Rack ,但是對於PHP。 這指定了應用程序的接口(與語言的運行方式無關)。 對於新請求,將創建應用程序對象的新實例。 據我所知,這對於PHP來說並不存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM