Php-fpm由於其特有的優勢已經逐漸成為這一階段大負載網站的首選。近期受朋友之託,將一個稍顯老舊的網站從apache+mod_php遷移到了nginx+php-fpm之上。其間碰到不少問題,除卻php版本升級帶來的相容性問題之外,很多相容性問題其實來自於php-fpm的特性。這裡就簡單的羅列一下所碰到的問題,以供大家參考,少走彎路為妙。
首當其衝的是$_SERVER["HTTP_REFERER"] 環境變數,這個問題經常出現在需要跳轉的頁面上,表現為跳轉到白板。
很多代碼習慣上用$_SERVER["HTTP_REFERER"] 擷取上次訪問的頁面URL,這對於mod_php來說,由於採用直接嵌入http伺服器的方法,PHP可以很容易的獲得HTTP_REFERER變數。但對於CGI方式的php-fpm來說,此環境變數無法擷取,我個人的解決方案是通過不斷重新整理一個cookie擷取。顯得很笨拙,但代碼改動的量很少。你也許會說這樣做容易被篡改,但事實上即便mod_php擷取的環境變數也是很容易被篡改的。
接下來是$_SERVER["HTTPS"],這個問題經常出現在跳轉上,如果發現所有的跳轉url出現異常多半是這個問題。
mod_php中$_SERVER["HTTPS"]變數只有在啟用了https之後才會出現,否則empty($_SERVER["HTTPS"]) === true,而作為php-fpm這個值是始終存在的,只是在http時$_SERVER["HTTPS"] === null而已。儘管$_SERVER["HTTPS"] == null 等價於empty($_SERVER["HTTPS"]) == true,但在“三等”條件下並不成立。
對應的$_SERVER變數問題還有x-forward*之類,這裡不再累述。
然後是rewrite規則,這個規則事實上是apache和nginx之間的相容問題,跟php無關。
個人覺得很apache和nginx的跳轉規則基本上是通用的甚至於只要用記事本做個全文替換就好。例如:
RewriteRule ^(.*.(css|js))$ min/index.php?f=$1 [L]
轉換為nginx
rewrite "^(.*.(css|js))$" /min/index.php?f=$1 last;
當然,nginx是不支援.htaccess的,需要寫入設定檔中去。
執行時間問題,對應的大多為502報錯。這個問題說實話我沒有很好的方法解決,只能提前規劃。
不同於mod_php的方式,在執行一個較長時間的指令碼時,一旦超出閥值(預設10秒)php-fpm會自動關閉執行,向前端返回502。個人覺得這相對於mod_php來說是一個保護性的設定,是優勢所在,不應該關閉。
進程式控制制類函數,相對用的應該不多。
php-fpm用的是非阻塞性質的線程池,不應該有這類函數出現,應當慎用。
一個竅門:$_ENV變數
相比mod_php來說,$_ENV變數是一個優勢,對於企業開發,特別是開發和營運分開的企業,這很容易開發出環境無關的代碼——營運修改$_ENV變數,開發讀取此變數,相互直接不需要太多交流。對應5.3 fpm設定檔中 env[TEMP] = /tmp 或者5.2 <value name=”environment”> <value name=”TMP”>/tmp</value>標籤