2010-02-27 65 views
4

我需要一些幫助來理解PHP的內部運作。請記住,在過去,我們曾經寫過TSR(終止並保持常駐)例程(Pre-windows era)嗎?一旦該程序執行完畢,它將保留在內存中,並可以通過某個熱鍵(alt或ctrl-鍵組合)重新執行。PHP架構:我該怎麼做?

我想在Web服務器/應用程序中使用類似的概念。比如說,我有common_functions.php,它由普通函數(如Generate_City_Combo()或Check_Permission()或Generate_User_Permission_list()等)組成,並運行在該apache/php服務器上運行的所有Web應用程序中。

在所有的模塊或應用程序的PHP文件,我可以寫:
require_once(common_functions.php);

它將在所有模塊和應用程序中包含該通用文件,並且工作正常。

我的問題是:如何在內部處理這個問題?假設我有: 兩個應用程序AppOne和AppTwo。
AppOne有兩種菜單選項AppOne_Menu_PQR和AppOne_Menu_XYZ
AppTwo有兩種菜單選項AppTwo_Menu_ABC和APPTwo_Menu_DEF

這四個菜單項的調用函數{像Generate_City_Combo(),或Check_Permission()或Generate_User_Permission_list()}從common_functions。 php

現在考慮以下情況: A)用戶XXX登錄並從他的個性化儀表板中點擊AppOne_Menu_PQR,然後按照所有屏幕和說明進行操作。這是一系列8-10頁的請求(屏幕),它是交互式的。結束後,用戶XXX從他的個性化儀表板中點擊AppTwo_Menu_DEF,並再次像早先的他/他通過所有屏幕和說明(約8-10頁/屏幕)一樣。然後用戶XXX註銷。

在B)用戶XXX日誌和爲所欲爲的情況下A.提到的同時,用戶也YYY登錄(從其他客戶機)並執行情景A.

提到的場景類似的事情A,它是同一屆會議。對於情景B,有兩個不同的會話。

假設所有菜單選項都調用Generate_User_Permission_list()和Generate_Footer()或許多菜單選項調用Generate_City_Combo()。

那麼PHP會每頁執行/包含common_functions.php多少次?每個會話?或每個PHP啓動/關閉?我的理解是common_functions.php將被執行一次每頁請求/循環/加載/屏幕,對不對?基本上每一次互動都有一次。

記住像Generate_City_Combo()或Generate_Footer()這樣的函數會產生相同的輸出或做同樣的事情,而不管誰或什麼時候調用。

我想限制一次,每個應用程序啓動和關閉。

這些只是例子。我的實際問題要複雜得多。在我的應用程序中,我想只調用一次Application_Startup()例程,這將創建理想的環境(如所有查找和參考數據結構,只讀數據,安全矩陣,菜單選項,上下文相關的業務執行邏輯等。 )。之後,所有來服務器的請求不必花費任何時間或資源來創建環境,但可以立即指「已創建環境」。

這是不是可行的PHP?怎麼樣?你能指點我到某個地方或一些解釋PHP內部工作的書嗎?

在此先感謝。

回答

2

PHP在一個完全獨立的執行框架中處理每個HTTP請求 - 沒有持續的進程運行來爲它們提供服務。 (您的網絡服務器正在運行,但每次加載PHP頁面時,都會調用一個單獨的PHP解釋器實例。)

如果您希望生成所需持久區域的時間很長,您可能希望考慮緩存磁盤從這些腳本輸出和第一加載緩存的版本,如果它是可用的(而不是過時的)。

+0

謝謝戴維。 有沒有辦法有一個? 很多次,我已經看到php應用程序創建對象實例左右中心與每個http請求。作爲老C開發人員,我覺得它非常高效。有出路嗎? 謝謝 Shailesh。 – 2010-02-27 04:36:42

+0

這是PHP工作方式的固有特性 - 它在技術上被設計爲一個預處理器(儘管它自創建以來已經有所改進)。 PHP解釋器無法同時處理多個請求,因爲它旨在由單獨的服務器調用(而不是單獨運行)。 – Amber 2010-02-27 06:21:06

1

PHP(在幾乎所有情況下)是面向頁。沒有Application_Startup()會維護HTTP請求的狀態。

您有時可以通過從數據庫或$ _SESSION加載/卸載序列化數據來模擬此過程,但會涉及開銷。另外,還有一些其他的情況下,一個memcached服務器可以優化這個爲好,但你通常不能使用那些與你典型的虛擬主機服務,如的cPanel。

如果我不得不建立一個像你所說的應用程序,我會將用戶選擇序列化到會話中,然後保存在數據庫中的會話之間持續存在的任何需要。

PHP有幾個ORM模塊,如Doctrine,它簡化了對象到數據庫的序列化。

+0

沒有相應的global.aspx或global.asa? – 2010-02-27 04:44:51

+0

nope有沒有,但你可以用php創建類似的東西:http://sarfraznawaz.wordpress.com/2009/09/08/application-variables-in-php/ – Sarfraz 2010-02-27 05:24:21

+0

Sarfraz是正確的,沒有像全球.aspx/global.asa在php中,他在鏈接中提出的建議使用序列化,並且存在與此相關的非序列化開銷。 這是PHP開發人員必須處理的事情。 – 2010-02-27 17:20:33

1

我會說你可能會過早地優化,但有希望。

由於您希望每個請求的穩定性,您經常需要在內存中多次複製已編譯的代碼;您不希望單獨的請求在相同的內存空間中運行並且存在競爭條件或數據損壞的風險!

這就是說,有numerous PHP Accelerators那裏將預編譯PHP代碼,大大加快包括和要求調用。

+0

有沒有辦法,可以像TomCat一樣開發Application Server? – 2010-02-27 04:47:31

0

在這裏,我很壞,但是隨着PThread的出現,似乎可能會出現針對實際解決方案刺傷的可能性,而不僅僅是實際上說「不,你不能用PHP來完成。「

一個人基本上可以使用CLI工具,socket_ *函數和PThreads在PHP中創建自己的多線程Web服務器。只聽端口80,添加請求,請求隊列,並啓動工作線程的一些數字來處理隊列。

可以根據請求隊列長度和操作系統的運行隊列長度來管理工作人員的數量。每隔幾秒,主線程就可以通過一個函數來管理工作池的大小。如果Web請求隊列長度大於某個常量時間,則操作系統的運行隊列長度和工作數量小於配置的最大值,則可以實例化另一個工作線程。如果Web請求隊列長度小於某個其他(較低)常量時間,則操作系統的運行隊列長度和工作數量大於配置的最小值,它可以告訴其中一個工作線程在完成當前請求時死亡。然後可以調整常量和配置的值以最大化服務器的所有吞吐量。類似的東西。

你必須做所有你自己的uri解析,你必須自己拼湊HTTP響應等,但工作線程可以實例化擴展Threaded的對象,或者重用先前實例化的Threaded對象。

Voila - PHP TomCat。