經過漫長的品質保證流程,PHP 4.1.0 終於釋出了!
[ 法文版 ]
PHP 4.1.0 包含其他幾項重要的改進
正如有些人可能注意到的,這個版本具有相當的歷史意義,因為這是我們有史以來第一次增加中間的數字!:) 這個前所未有的變更主要有兩個原因:新的輸入介面,以及由於版本控制支援而導致模組的二進位相容性被破壞。
以下說明新的輸入機制。關於 PHP 4.1.0 的完整變更列表,請參閱變更日誌。
首先,必須強調的是,無論您在以下文字中讀到什麼,PHP 4.1.0 **仍然支援** 舊版中的舊輸入機制。舊的應用程式應該可以繼續正常運作,無需修改!
現在我們已經釐清這點,讓我們繼續 :)
由於各種原因,依賴開啟 register_globals 的 PHP 設定(例如,表單、伺服器和環境變數自動成為全域命名空間的一部分)通常很容易受到不同程度的攻擊。例如,以下程式碼:
<?php
if (authenticate_user()) {
$authenticated = true;
}
...
?>
可能存在漏洞,因為遠端使用者可以簡單地將 'authenticated' 作為表單變數傳遞,即使 authenticate_user() 返回 false,$authenticated 的值實際上也會被設定為 true。雖然這看起來是一個簡單的例子,但實際上,相當多的 PHP 應用程式最終都因為這個錯誤的功能而容易受到攻擊。
雖然在 PHP 中編寫安全的程式碼是完全可行的,但我們認為 PHP 太容易編寫不安全的程式碼這個事實很糟糕,因此我們決定嘗試進行深遠的改變,並棄用 register_globals。顯然,由於世界上絕大多數的 PHP 程式碼都依賴這個功能的存在,我們目前沒有任何計畫在可預見的未來將其從 PHP 中移除,但我們決定鼓勵使用者盡可能關閉它。
為了幫助使用者在關閉 register_globals 的情況下建構 PHP 應用程式,我們新增了幾個新的特殊變數,可以取代舊的全域變數。新增了 7 個特殊的陣列:
現在,除了這些變數包含這些特殊資訊之外,它們在另一個方面也很特殊——它們在任何範圍內都是自動全域的。這表示您可以在任何地方存取它們,而無需先將它們宣告為「全域」。例如:
<?php
function example1()
{
print $_GET["name"]; // 可以正常運作,不需要 'global $_GET;'!
}
?>
將可以正常運作!我們希望這個事實能稍微減輕將舊程式碼遷移到新程式碼的痛苦,而且我們相信它會讓編寫新程式碼變得更容易。另一個巧妙的技巧是,在 $_SESSION 陣列中建立新的項目會自動將它們註冊為 session 變數,就像您呼叫 session_register() 一樣。這個技巧僅限於 session 模組——例如,在 $_ENV 中設定新的項目**不會**執行隱式的 putenv()。
PHP 4.1.0 預設仍然將 register_globals 設定為開啟。這是一個過渡版本,我們鼓勵應用程式作者,尤其是廣泛使用的公開應用程式作者,將他們的應用程式更改為在 register_globals 設定為關閉的環境中運作。當然,他們應該利用 PHP 4.1.0 中提供的新功能,讓這個過渡更容易。
自 PHP 下一個半主要版本開始,PHP 的新安裝預設將 register_globals 設定為關閉。別擔心!現有的安裝,如果 php.ini 檔案中 register_globals 已經設定為開啟,將不會受到影響。只有當您在新機器上安裝 PHP 時(通常是新使用者),才會受到影響,而且即使如此,您也可以選擇將其開啟。
注意:其中一些陣列具有舊名稱,例如 $HTTP_GET_VARS。這些名稱仍然有效,但我們鼓勵使用者切換到新的較短的自動全域版本。
感謝 Shaun Clowes (shaun at securereality dot com dot au) 指出並分析了這個問題。