PHP核心探索 Apache模組介紹

2021-08-03 16:14:29 字數 2909 閱讀 4759

apache概述

apache是目前世界上使用最為廣泛的一種web server,它以跨平台、高效和穩定而聞名。按照去年官方統計的資料,apache伺服器的裝機量占該市場60%以上的份額。尤其是在x(unix/linux)平台上,apache是最常見的選擇。其它的web server產品,比如iis,只能執行在windows平台上,是基於微軟.net架構技術的不二選擇。

apache支援許多特性,大部分通過模組擴充套件實現。常見的模組包括mod_auth(許可權驗證)、mod_ssl(ssl和tls支援) mod_rewrite(url重寫)等。一些通用的語言也支援以apache模組的方式與apache整合。 如perl,python,tcl,和php等。

apache並不是沒有缺點,它最為詬病的一點就是變得越來越重,被普遍認為是重量級的webserver。所以,近年來又湧現出了很多輕量級的替代產品,比如lighttpd,nginx等等,這些webserver的優點是執行效率很高,但缺點也很明顯,成熟度往往要低於apache,通常只能用於某些特定場合。

apache元件邏輯圖

apache是基於模組化設計的,總體上看起來**的可讀性高於php的**,它的核心**並不多,大多數的功能都被分散到各個模組中,各個模組在系統啟動的時候按需載入。你如果想要閱讀apache的源**,建議你直接從main.c檔案讀起,系統最主要的處理邏輯都包含在裡面。

mpm(multi -processing modules,多重處理模組)是apache的核心元件之一,apache通過mpm來使用作業系統的資源,對程序和執行緒池進行管理。apache為了能夠獲得最好的執行效能,針對不同的平台(unix/linux、window)做了優化,為不同的平台提供了不同的mpm,使用者可以根據實際情況進行選擇,其中最常使用的mpm有prefork和worker兩種。至於您的伺服器正以哪種方式執行,取決於安裝apache過程中指定的mpm編譯引數,在x系統上預設的編譯引數為prefork。由於大多數的unix都不支援真正的執行緒,所以採用了預派生子程序(prefork)方式,象windows或者solaris這些支援執行緒的平台,基於多程序多執行緒混合的worker模式是一種不錯的選擇。對此感興趣的同學可以閱讀有關資料,此處不再多講。apache中還有乙個重要的元件就是apr(apache portable runtime library),即apache可移植執行庫,它是乙個對作業系統呼叫的抽象庫,用來實現apache內部元件對作業系統的使用,提高系統的可移植性。apache對於php的解析,就是通過眾多module中的php module來完成的。

apache的邏輯構成以及與作業系統的關係

php與apache

當php需要在apache伺服器下執行時,一般來說,它可以mod_php5模組的形式整合, 此時mod_php5模組的作用是接收apache傳遞過來的php檔案請求,並處理這些請求, 然後將處理後的結果返回給apache。如果我們在apache啟動前在其配置檔案中配置好了php模組(mod_php5), php模組通過註冊apache2的ap_hook_post_config掛鉤,在apache啟動的時候啟動此模組以接受php檔案的請求。

除了這種啟動時的載入方式,apache的模組可以在執行的時候動態裝載, 這意味著對伺服器可以進行功能擴充套件而不需要重新對源**進行編譯,甚至根本不需要停止伺服器。 我們所需要做的僅僅是給伺服器傳送訊號hup或者ap_sig_graceful通知伺服器重新載入模組。 但是在動態載入之前,我們需要將模組編譯成為動態鏈結庫。此時的動態載入就是載入動態鏈結庫。 apache中對動態鏈結庫的處理是通過模組mod_so來完成的,因此mod_so模組不能被動態載入, 它只能被靜態編譯進apache的核心。這意味著它是隨著apache一起啟動的。

apache是如何載入模組的呢?我們以前面提到的mod_php5模組為例。 首先我們需要在apache的配置檔案httpd.conf中新增一行:

1loadmodule php5_module modules/mod_php5.so

這裡我們使用了loadmodule命令,該命令的第乙個引數是模組的名稱,名稱可以在模組實現的原始碼中找到。 第二個選項是該模組所處的路徑。如果需要在伺服器執行時載入模組, 可以通過傳送訊號hup或者ap_sig_graceful給伺服器,一旦接受到該訊號,apache將重新裝載模組, 而不需要重新啟動伺服器。

在配置檔案中新增了所上所示的指令後,apache在載入模組時會根據模組名查詢模組並載入, 對於每乙個模組,apache必須保證其檔名是以「mod_」開始的,如php的mod_php5.c。 如果命名格式不對,apache將認為此模組不合法。apache的每乙個模組都是以module結構體的形式存在, module結構的name屬性在最後是通過巨集standard20_module_stuff以__file__體現。 關於這點可以在後面介紹mod_php5模組時有看到。這也就決定了我們的檔名和模組名是相同的。 通過之前指令中指定的路徑找到相關的動態鏈結庫檔案後,apache通過內部的函式獲取動態鏈結庫中的內容, 並將模組的內容載入到記憶體中的指定變數中。

在真正啟用模組之前,apache會檢查所載入的模組是否為真正的apache模組, 這個檢測是通過檢查module結構體中的magic欄位實現的。 而magic欄位是通過巨集standard20_module_stuff體現,在這個巨集中magic的值為module_magic_cookie, module_magic_cookie定義如下:

1#define module_magic_cookie 0x41503232ul /* "ap22" */

最後apache會呼叫相關函式(ap_add_loaded_module)將模組啟用, 此處的啟用就是將模組放入相應的鍊錶中(ap_top_modules鍊錶: ap_top_modules鍊錶用來儲存apache中所有的被啟用的模組,包括預設的啟用模組和啟用的第三方模組。)

php核心探索 常量

在php中常量的結構只是在變數的基礎上新增了一些額外的元素 typedef struct zend constant zend constant php常量定義方式 define think in php define定義常量過程 類常量定義 此處不做介紹 值型別判斷和處理 c.value val ...

Apache載入php模組

vc6就是legacy visual studio 6 compiler,就是使用這個編譯器編譯的。vc9就是the visual studio 2008 compiler,就是用微軟的vs編輯器編譯的。那我們如何選擇php版本呢?如果你是在windows下使用apa php呢?apache php...

PHP核心探索筆記 函式

函式的定義是乙個將函式名註冊到函式列表的過程 1.詞法分析 function將會生成t function標記 2.語法分析 3.生成中間 生成的中間 為 zend declare function 根據這個中間 及運算元對應的op type。我們可以找到中間 的執行函式為 zend declare ...