PHP工作模型與運行機制_PHP教程

來源:互聯網
上載者:User
PHP的工作模型非常特殊。從某種程度上說,PHP和ASP、ASP.NET、JSP/Servlet等流行的Web技術,有著本質上的區別。

以Java為例,Java在Web應用領域,有兩種技術:Java Servlet和JSP(Java Server Page)。Java Servlet是一種特殊類型的Java程式,它通過實現相關介面,處理Web伺服器發送過來的請求,完成相應的工作。JSP在形式上是一種類似於PHP的指令碼,但是事實上,它最後也被編譯成Servlet。也就是說,在Java解決方案中,JSP和Servlet是作為獨立的Java應用程式執行的,它們在初始化之後就駐留記憶體,通過特定的介面和Web伺服器通訊,完成相應工作。除非被顯式地重啟,否則它們不會終止。因此,可以在JSP和Servlet中使用各種緩衝技術,例如資料庫連接池。

ASP.NET的機制與此類似。至於ASP,雖然也是一種解釋型語言,但是仍然提供了Application對象來存放應用程式級的全域變數,它依託於ASP解譯器在IIS中駐留的進程,在整個應用程式的生命期有效。

PHP是一種純解釋型在服務端執行的可以內嵌HTML的指令碼語言,尤其適合開發Web應用程式。請求一個 PHP 指令碼時,PHP 會讀取該指令碼,並將其編譯為 Zend 作業碼,這是要執行的代碼的一種二進位表示形式。隨後,此作業碼由 PHP 執行並丟棄。 PHP指令碼在每次被解釋時進行初始化,在解釋完畢後終止運行。這種運行是互相獨立的,每一次請求都會建立一個單獨的進程或線程,來解釋相應的分頁檔。頁面建立的變數和其他對象,都只在當前的頁面內部可見,無法跨越頁面訪問。在終止運行後,頁面中申請的、沒有被代碼顯式釋放的外部資源,包括記憶體、資料庫連接、檔案控制代碼、Socket串連等,都會被強行釋放。也就是說,PHP無法在語言層級上實現直接存取跨越頁面的變數,也無法建立駐留記憶體的對象。

"; TestStaticVar(); ?> 

在這個例子中,定義了一個名為StaticVarTester的類,它僅有一個公用的靜態成員$StaticVar,並被初始化為0。然後,在TestStaticVar()函數中,對StaticVarTester :: $StaticVar進行累加操作,並將它列印輸出。

熟悉Java或C++的開發人員對這個例子應該並不陌生。$StaticVar作為StaticVarTester類的一個靜態成員,只在類被裝載時進行初始化,無論StaticVarTester類被執行個體化多少次,$StaticVar都只存在一個執行個體,而且不會被多次初始化。因此,當第一次調用TestStaticVar()函數時,$StaticVar進行了累加操作,值為1,並被儲存。第二次調用TestStaticVar()函數,$StaticVar的值為2。

列印出來的結果和我們預料的一樣:

StaticVarTester :: StaticVar = 1 StaticVarTester :: StaticVar = 2 

但是,當瀏覽器重新整理頁面,再次執行這段代碼時,不同的情況出現了。在Java或C++裡面,$StaticVar的值會被儲存並一直累加下去,我們將會看到如下的結果:

StaticVarTester :: StaticVar = 3 StaticVarTester :: StaticVar = 4 … 

但是在PHP中,由於上文敘及的機制,當前頁面每次都解釋時,都會執行一次程式初始化和終止的過程。也就是說,每次訪問時,StaticVarTester都會被重新裝載,而下列這行語句 public static $StaticVar = 0; 也會被重複執行。當頁面執行完成後,所有的記憶體空間都會被回收,$StaticVar這個變數(連同整個StaticVarTester類)也就不複存在。因此,無論重新整理頁面多少次,$StaticVar變數都會回到起點:先被初始化為0,然後在TestStaticVar()函數調用中被累加。所以,我們看到的結果永遠是這個:

StaticVarTester :: StaticVar = 1 StaticVarTester :: StaticVar = 2 

PHP這種獨特的工作模型的優勢在於,基本上解決了令人頭疼的資源泄漏問題。Web應用的特點是大量的、短時間的並發處理,對各種資源的申請和釋放工作非常頻繁,很容易導致泄漏甚至崩潰。PHP的運行機制決定它不存在常規的崩潰問題(頂多連線逾時指令碼停止執行),可以說PHP是較穩定的Web應用。但是,這種機制的缺點也非常明顯。最直接的後果是,PHP在語言層級無法實現跨頁面的緩衝機制。這種緩衝機制缺失造成的影響,可以分成兩個方面:

一是對象的緩衝。眾所周知,很多設計模式都依賴於對象的緩衝機制,建立和銷毀對象是很費時間的,因為建立一個對象要擷取記憶體資源或者其它更多資源,對於需要頻繁應付大量並發的服務端軟體更是如此。因此,對象緩衝的缺失,理論上會極大地降低速度。應儘可能減少建立和銷毀對象的次數來提高服務程式的效率,由於 PHP目前還不支援多線程,也就無法像Java一樣通過線程池調度來彌補這一缺陷;但可以使用第三方軟體如Memcachd來實現PHP的對象緩衝機制,達到減少對象建立和銷毀的時間來提高服務程式的效率。Memcachd將PHP編譯後的 作業碼緩衝並在記憶體中儲存這個作業碼,並在下一次調用該頁面時重用它,這會節省很多時間。比較常用的緩衝還有有 eAccelerator,另一種流行的 eAccelerator 替代工具是 Alternative PHP Cache(APC)。

二是資料庫連接的緩衝。對於MySQL,PHP提供了一種內建的資料庫緩衝機制,即用mysql_pconnect()代替mysql_connect() 來開啟資料庫而已。PHP會自動回收被廢棄的資料庫連接,以供重複使用。在實際應用中,這種持久性資料庫連接往往會導致資料庫連接的偽泄漏現象:在某個時間,並發的資料庫連接過多,超過了MySQL的最大串連數,從而導致新的進程無法串連資料庫。但是過一段時間,當並發數減少時,PHP會釋放掉一些串連,網站又會恢複正常。出現這種現象的原因是,當使用pconnect時,Apache 的httpd進程會不釋放connect,而當Apache的httpd進程數超過了mysql的最大串連數時,就會出現無法串連的情況。因此,需要小心地調整Apache和Mysql的配置,以使Apache的httpd進程數不會超出MySQL的最大串連數。筆者經過實踐,在PHP5和 Oracle10g的串連中,由於頻於資料庫連接,有時候還會出現資料庫丟失串連的情況(Oracle官方有針對PHP的增強包,不知是否可以解決此問題,筆者未試)。

PHP的工作模型即是缺點也是優勢,從本質上說,這就是PHP 的獨特之處。

若以FastCGI模式運行php,解析php.ini、載入全部擴充並重初始化全部資料結構這些都只在進程啟動時發生一次。一個額外的好處是,持續資料庫連接可以工作。Nginx+PHP(FastCGI)是個不錯的選擇。

http://www.bkjia.com/PHPjc/752422.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/752422.htmlTechArticlePHP的工作模型非常特殊。從某種程度上說,PHP和ASP、ASP.NET、JSP/Servlet等流行的Web技術,有著本質上的區別。 以Java為例,Java在Web應用領域,...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.