[翻譯] PHP 7.2 中棄用的功能

茄子發表於2017-02-18

PHP RFC: 7.2 棄用功能 已獲批准。讓我們來看一看,有哪些功能未來會丟擲棄用提醒:

__autoload

__autoload 魔術方法,已經被 PHP 5.1 中的 spl_autoload_register 取代,並且在文件中不建議使用。spl_autoloadregister() 的一個主要優點,是能夠提供多個組合的自動載入器,從而降低庫的互操作性。這兩種載入機制是互斥的,使用 \_autoload 的程式碼不能與使用 spl_autoloadregister 程式碼互動操作。由於後者更常用,並且也被 Composer 使用,所以 \_autoload() 機制現在僅具有非常有限的適用性。

$php_errormsg

當一個非致命錯誤被丟擲時,如果在 ini 中設定了 track_errors (預設情況下已禁用),並且該錯誤未被錯誤處理器程式處理,則會在本地作用域中建立 $php_errormsg 變數。

整個行為非常神奇,除了 ini 相關的部分。error_get_last 函式提供了一種更乾淨的方式,來檢索最後一個錯誤。PHP 7 還提供了 error_clear_last 函式,覆蓋了 $php_errormsg 最後可能的用例,並且沒有神奇的作用域操作。

create_function()

create_function() 是對 eval() 的簡單包裝。此函式可以建立一個函式,函式的引數列表和函式主體作為字串引數傳入。在 PHP 5.3 引入閉包之前,它提供了一種建立近似於 lambda 函式的方法。

由於其操作的性質,create_function() 除了是潛在的安全問題來源之外,還具有非常差的效能和記憶體使用特性。在各種情況下,使用真正的閉包是首選。

mbstring.func_overload

在 ini 中設定 mbstring.func_overload 將允許用 mbstring 擴充套件中的相似功能替換掉字串函式的子集。例如,strlen() 將不再返回以位元組為單位的字串長度,而是根據當前選擇的內部編碼返回程式碼點中的長度。

這意味著使用 mbstring.func_overload 的程式碼,與幾乎所有在基本字串操作正常工作的假設下編寫的程式碼都不相容。一些庫完全禁止 func_overload (例如 Symfony),其它的則會出現一些不可察覺的行為變化。希望支援 func_overload 的程式碼需要有在普通字串函式和具有8位編碼的 mbstring 函式之間切換的條件(但是,通常只有加密庫才會這麼做)。

(unset)cast

(unset)cast 轉換一個值為 null。

這表示 (unset)expr 只是一個總返回 null 並且沒有其它副作用的表示式。除了無用以外,也容易讓人懵逼。很多人合理的假設 (unset)$a 的行為類似於 unset($a) ,而實際上沒那麼回事。

parse_str() 不傳入第二個引數

parse_str() 函式用於將查詢字串解析為第二個引數傳入的陣列,如果沒有傳入,則解析為本地符號表。

第二種行為是來自 register_globals 黑暗時代的殘餘。當處理使用者提供的資料時,存在嚴重的安全隱患。

gmp_random()

gmp_random() 函式返回一個 0 到 2**($n*BITS_PER_LIMB)-1 之間的隨機 GMP 數,其中 $n 是函式引數,BITS_PER_LIMB 是 GMP/MPIR 實現的平臺特定引數,未向使用者公開。因此,使用此功能需要猜測 limb 大小,並且有平臺依賴性。

作為補救 PHP 5.6 引入了可以精確控制使用的隨機數範圍的 gmp_random_bits() 和 gmp_random_range() 函式。應始終優先使用這些函式,而不是 gmp_random()。

each()

each() 函式被用於遍歷一個陣列,類似於 foreach。每次呼叫時返回一個具有當前 key 和 value 的陣列,並將內部陣列指標移動到下一個位置。手冊中介紹的典型用法如下:

reset($array);
while (list($key, $val) = each($array)) {
    echo "$key => $val\n";
}

each() 函式不如 foreach,並且比它慢十倍。

assert() 傳入字元引數

assert() 函式具有兩種操作模式:如果它傳入的不是字串,它會斷言該值是否為真。如果傳入一個字串則先執行 eval(),然後檢查 eval() 的結果是否為真。

在 PHP 7 之前,這種行為是阻止斷言表示式求值的唯一方法。從 PHP 7 開始,可以在 ini 中設定 zend.assertions 的值,來避免對斷言表示式求值。因此,不再需要支援隱式評估的字串引數。

assert() 的這種行為使得很容易引入微妙的遠端程式碼執行漏洞。

錯誤處理器的 $errcontext 引數

$errcontext 是使用 set_error_handler() 設定錯誤處理程式時的最後一個引數。此引數為包含錯誤生成處的所有區域性變數的陣列。

這個功能對於優化有影響,因為 $errcontext 可用於修改當前範圍中的所有引用和變數。據我所知,這個功能幾乎無用,這裡的權衡是不值得的。如果人們希望在錯誤的時候檢查變數狀態,他們應該使用適當的偵錯程式。

請注意,錯誤上下文僅包含錯誤發生處的區域性變數。包含 $this 和函式引數的錯誤回溯,會通過 debug_backtrace() 保持可用。

更多更改和投票細節,請檢視 RFC

本作品採用《CC 協議》,轉載必須註明作者和本文連結

Night gathers, and now my watch begins.

相關文章