首頁  >  文章  >  後端開發  >  PHP 7.4允許從 __toString() 拋出例外

PHP 7.4允許從 __toString() 拋出例外

藏色散人
藏色散人原創
2019-11-30 14:41:322860瀏覽

PHP 7.4允許從__toString() 拋出例外(Allow Exceptions from __toString())

介紹

#目前禁止從__toString()拋出異常,並將導致致命錯誤。這就使得呼叫任意程式碼變得很危險,並使其成為一個有問題的通用API。此RFC旨在取消此限制。

當前行為的基本原理是,在整個引擎和標準庫的許多地方都執行了字串轉換,並不是所有地方都準備「正確地」處理異常,即盡可能早地處理異常。

從技術角度來看,這種限制最終是無效的,因為字串轉換期間的異常​​仍然可以由將可恢復錯誤轉換為異常的錯誤處理程序觸發:

set_error_handler(function() {
    throw new Exception();
});
 
try {
    (string) new stdClass;
} catch (Exception $e) {
    echo "(string) threw an exception...\n";
}

#事實上,Symfony利用這個漏洞來繞過目前的限制。不幸的是,這依賴於$errcontext參數,它在PHP 8中消失了.

儘管如此,在我們對該程式碼庫中的字串轉換進行了全面審核之前,過去關於該主題的討論一直沒有放鬆這種限制。這已在附加的實作請求中完成。

建議

允許從__toString()拋出異常,它的行為與往常一樣。不再觸發致命錯誤。

另外,將「不能轉換為字串」和「__toString()必須回傳一個字串值」可恢復的致命錯誤轉換為正確的錯誤異常,這與PHP 7中建立的錯誤策略一致。

擴充準則

想要優雅地處理來自字串轉換的例外的擴充作者,應該考慮以下準則:

● 如果zval_get_string( )、convert_to_string()和friends產生一個異常,它們仍然會產生一個字串。這個字串被保證是暫存的。這意味著沒有必要釋放它,但可以這樣做。在上下文中,您可以選擇更方便的選項。

● 如果從物件到字串的轉換失敗,則字串轉換的結果將為空字串,如果將陣列轉換為字串,並且錯誤處理程序將結果通知提升為異常,則為「Array」。 (這種行為和以前一樣。)

● 通常情況下,使用通常的if (EG(exception))檢查來檢查是否拋出了異常就足夠了:

zend_string *str = zval_get_string(val);
if (EG(exception)) {
    // Possibly free other resources here.
    return;
}

除此之外,還提供了一些幫助api,將轉換建模為容易出錯的操作:

// Like zval_get_string() but returns NULL on conversion failure.
zend_string *str = zval_try_get_string(val);
if (!str) {
    // Possibly free other resources here.
    return;
}
// Main code.
zend_string_release(str);
 
 
// Like zval_get_tmp_string() but returns NULL on conversion failure.
zend_string *tmp, *str = zval_try_get_tmp_string(val, &tmp);
if (!str) {
    // Possibly free other resources here.
    return;
}
// Main code.
zend_tmp_string_release(tmp);
 
 
// Like convert_to_string() but returns a boolean indicating conversion success/failure.
if (!try_convert_to_string(val)) {
    // Possibly free other resources here.
    return;
}
// Main code.

如果轉換失敗,try_convert_to_string()將不會修改原始值。因此,使用它比使用convert_to_string()和異常檢查更安全。

雖然檢查每個字串轉換肯定會使您處於安全的一方,但忽略這些檢查通常只會導致一些不必要的計算和可能的冗餘警告。您應該注意的主要事情是修改持久性結構(如資料庫)的操作。

不向後相容的變更

從可恢復的致命錯誤到錯誤異常的轉換在技術上是BC中斷的。

翻譯:https://wiki.php.net/rfc/tostring_exceptions

以上是PHP 7.4允許從 __toString() 拋出例外的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn