最近在我的 Windows 7 開發機器上安裝了 Apache 2.2 和 PHP 5.2.17,我想分享一下關於如何設定載入正確版本 OpenSSL DLL 的心得。許多人在其他地方發文提到了如果載入錯誤版本的 DLL 會導致「DLL 地獄」。
首先,安裝 Apache 2.2 並檢查其運作,然後從 http://windows.php.net/download/. 下載適用於 Windows 的 PHP 二進制檔案。請注意,根據該頁面側邊欄的說明,目前建議與 Apache 2 搭配使用的 PHP 版本是 5.2.17,即使它是一個較舊的版本。此外,這個版本附帶了使用 OpenSSL 所需的所有 DLL 檔案,無需像舊版 PHP 手冊頁面建議的那樣重新編譯。
驗證 PHP 安裝後,取消註解以下這一行來啟用 OpenSSL 支援:
extension=php_openssl.dll
它位於 php.ini 檔案中,你可以在 PHP 目錄中找到它(我假設你將其放在 c:/PHP)。接下來檢查 php_openssl.dll 的位置,你應該可以在 c:/PHP/ext 中找到它。同樣在 php.ini 中找到 extension_dir 這個鍵值,並將其值更改為 c:/php/ext。然後,將此位置添加到你的 PATH 環境變數的末尾(無需重新開機)。
此時,當你啟動 Apache 時,它會嘗試載入 php_openssl.dll,但如果你的設定與我的類似,你會看到一個錯誤。我習慣手動啟動 Apache,錯誤會顯示在一個對話方塊中:「在動態連結程式庫 LIBEAY32.dll 中找不到序數 4114。」(我不確定如果你將 Apache 作為服務啟動是否會收到此訊息)。Apache 日誌中也包含一條錯誤訊息,指出無法載入 php_openssl.dll,但該訊息並未提及 libeay32.dll。歡迎來到 DLL 地獄。
Libeay32.dll 出現是因為 php_openssl.dll 依賴它(以及 ssleay32.dll)。我認為發生的情況是 Apache 首先嘗試以程式設計方式從 extension_dir 鍵值指定的路徑載入 php_openssl.dll。但是,載入所謂的相依 DLL 的工作則留給 Windows 的預設機制。如果 Windows 找到不相容版本的相依 DLL,就會出現錯誤。
因此,顯然解決方法是確保載入正確版本的 libeay32.dll。在我的機器上,至少有三個其他處理程序載入了不同版本的這個 DLL。它們包括 Mozy 備份用戶端、Windows 檔案總管(因為 Mozy 在檔案總管中安裝了支援)和 OpenOffice 套件。在這方面,我的機器與專用伺服器完全不同,在專用伺服器上,人們可能希望盡可能減少額外處理程序。大概在伺服器上,可以遵循建議將 DLL 複製到 system32 目錄的建議。但我不會透過進行系統範圍的更改來干擾我的其他程式。
那麼該怎麼辦?我發現關於 Windows 如何搜尋 DLL 的可用資訊並不是很有用,主要是我不理解它。但它確實說 Windows 首先搜尋的地方是「載入應用程式的目錄」。
長話短說,經過大量的實驗,我得出了一個關鍵的認識——「應用程式」是 APACHE,而不是 PHP。所以我將 libeay32.dll 複製到 Apache2.2/bin 目錄。問題解決了。沒有錯誤訊息,執行 phpinfo 確認 OpenSSL 已存在且已啟用。
祝你好運,遠離 DLL 地獄。