亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

遷移到 PHP 8.1 - 如何修復(fù)已棄用的將 null 傳遞給參數(shù)錯(cuò)誤 - 重命名函數(shù)中的構(gòu)建
P粉420868294
P粉420868294 2024-01-10 16:21:21
0
2
710

PHP 8.1 已棄用將 null 作為參數(shù)傳遞給許多核心函數(shù)。我的主要問題是htmlspecialchars(php)trim(php) 等函數(shù),其中null 不再默默轉(zhuǎn)換為空字符串。

為了在不使用大量程式碼的情況下解決此問題,我嘗試重命名原始內(nèi)建函數(shù),並將它們替換為將輸入從 null 轉(zhuǎn)換為(空)字串的包裝器。

這種方法的主要問題是,函數(shù) rename_function(PECL apd) 不再起作用,上次更新是在 2004 年1。

我需要對(duì)內(nèi)建函數(shù)進(jìn)行某種重寫,以避免每次呼叫函數(shù)時(shí)都編寫空檢查,從而使我的所有程式碼變大兩倍。

我能想到的唯一其他解決方案是僅使用我的自訂函數(shù),但這仍然需要遍歷我擁有的所有程式碼和第三方程式庫。

在 PHP 8.1 中,當(dāng)將 null 傳遞給內(nèi)建函數(shù)時(shí),它不再默默地轉(zhuǎn)換為空字串。


  1. https://pecl.php.net/package/apd

#
P粉420868294
P粉420868294

全部回覆(2)
P粉811329034

我想(作為補(bǔ)充,現(xiàn)有的答案得到了我的支持)就如何看待和解決此類「問題」描繪了一幅不同的圖畫。它並沒有減少所概述的方法的正確性或錯(cuò)誤性,而只是一種希望互惠互利的附加觀點(diǎn)。每個(gè)項(xiàng)目都是不同的。

給定前提:

那麼這對(duì)我來說(首先)看起來是一個(gè)報(bào)告問題。透過不報(bào)告 E_DEPRECATED。

這樣做的好處是(不僅是您的程式碼),現(xiàn)在知道您的程式碼帶有棄用通知。報(bào)告確實(shí)有效。

另一方面,壓制棄用通知可能會(huì)讓它們消失。如果您丟失了程式碼庫帶有棄用通知的訊息,從技術(shù)上講,從資訊遺失中恢復(fù)可能仍然很容易(再次報(bào)告棄用通知),但是如果更改的時(shí)間延長了,現(xiàn)在可能會(huì)出現(xiàn)壓倒性的雜訊(E_TOO_MUCH_NOISE)。

那麼程式碼不沉默其實(shí)是一件壞事嗎?或者說可以轉(zhuǎn)化為利益嗎?我寧願(yuàn)選擇後者。不管怎樣,我們已經(jīng)在處理這些資訊了。

因此,在這種情況中,我的想法是一般不抑制棄用通知,而是「靜默」函數(shù)呼叫。這很容易,但無論從好的方面還是從壞的方面來說,這都是愚蠢的:

trim($mixed);   #1  ->     @trim($mixed);   #2

這當(dāng)然是一個(gè)可以使用標(biāo)準(zhǔn)文字工具應(yīng)用於程式碼庫的操作。它還會(huì)向您顯示過去已經(jīng)使用過 @ 抑制運(yùn)算子的位置:

@trim($mixed);  #3  ->     @@trim($mixed);  #4

如果您是PHP 開發(fā)人員,在編輯器中查看此類程式碼(對(duì)於情況#2-#4),他們會(huì)立即向您尖叫,並且對(duì)於所有四種情況至少都會(huì)吸引您的注意($mixed)。

感謝您沒有保持沉默,我們讓這些地方尖叫,只是不是在運(yùn)行時(shí)1。

與第一種透過不報(bào)告 E_DEPRECATED 來保持沉默的方法不同,這種方法很容易丟失訊息,而訊息是透過使用所有 @ 符號(hào)來保存的。

它對(duì)解決噪音問題有幫助嗎?如果我們停止在這裡工作,那就完全不行了?,F(xiàn)在我們會(huì)在程式碼上塗上@-符號(hào),決定不採取進(jìn)一步的操作,這樣我們就可以使用第一個(gè)解決方案(不報(bào)告棄用訊息)來完成它,而無需觸及程式碼。 p>

那麼它的好處是什麼?好吧,儘管程式碼現(xiàn)在靜默運(yùn)行,PHP 仍然提供診斷訊息。也就是說,現(xiàn)在可以將 PHP 錯(cuò)誤處理程序註冊(cè)為偵聽器(執(zhí)行程式碼時(shí))。

僅在程式碼級(jí)別,很容易檢查這些位置,因?yàn)?@ 符號(hào)(通常)也很容易在程式碼中發(fā)現(xiàn)。

第二部分很重要,因?yàn)閮嵐芏鄠€(gè)地方可能會(huì)受到棄用的影響,但一定不能有一個(gè)解決方案來解決所有問題(我更喜歡遠(yuǎn)離“一刀切” '解決方案』」(如果可能的話),但特別是在問題上下文中PHP 8.1 發(fā)生了變化,我可以想像根據(jù)使用地點(diǎn)會(huì)有不同的需求。

例如,在模板程式碼(輸出)中,具體類型不是一個(gè)問題,因此轉(zhuǎn)換為字串很可能是首選解決方案:

@trim($mixed);     ->     trim((string)$mixed)
@@trim($mixed);    ->     @trim((string)$mixed)

模板(輸出)保持穩(wěn)定。

但對(duì)於實(shí)際的輸入處理,棄用通知可能會(huì)發(fā)現(xiàn)值得修復(fù)的實(shí)際潛在缺陷,例如缺少預(yù)設(shè)值(使事情變得過於複雜)、值的處理不明確(空與空、字串、布林與數(shù)字)與PHP 中的陣列與物件)或一般的$mixed 混淆。

這樣的 trim($mixed) 可能是被遺忘多年的安全防護(hù),從未進(jìn)行過升級(jí)(有更好的安全防護(hù)可用)。對(duì)於這樣的程式碼,我很確定我已經(jīng)想要並要求$mixed 實(shí)際上是$string before 我使用trim ()。原因很簡單,至少直接想到兩件事:

  • a) 不再需要 trim() - 它可以被刪除(我最喜歡的修復(fù)之一:刪除程式碼?。?- 或 -李>
  • b)它正在進(jìn)行字串工作,那麼我有一個(gè)問題,因?yàn)槲也幌M腥魏畏亲执臇|西存在。問題在於,它通常不適用於霰彈槍方法(Gie?kanne 有人嗎?)。

使用 $mixed 進(jìn)行修補(bǔ)是完全有效的? ''如果原始使用是字串或null。

@trim($mixed);     ->     trim($mixed ?? '')
@@trim($mixed);    ->     @trim($mixed ?? '')

但除此之外,例如像 42 這樣的數(shù)字,將拋出 TypeError,而不是棄用訊息。這可以區(qū)分正在運(yùn)行的程式碼和未運(yùn)行的程式碼。

因此,這裡還有更多需要維護(hù)的地方,例如檢查位置,如果可能的話進(jìn)一步聚類,然後應(yīng)用更多專用修復(fù)程序。它可能會(huì)揭示缺少的測(cè)試或斷言,需要一些時(shí)間來穩(wěn)定整個(gè)應(yīng)用程式流程等。

在這種情況下,要完成程式碼的遷移,進(jìn)行集群,處理空合併運(yùn)算符,並為真正的修復(fù)做適當(dāng)?shù)奈臅ぷ?。一旦完成了使用空合併運(yùn)算符的非明顯錯(cuò)誤抑制並刪除了 @ 抑制運(yùn)算符,如果修復(fù)計(jì)劃未捕獲這些信息,您可能會(huì)丟失這些信息。

當(dāng)我在這些地方看起來受過更多教育時(shí),當(dāng)我發(fā)現(xiàn)自己撓頭或揉眼睛時(shí),我並不感到驚訝。然後我提醒自己,這些錯(cuò)誤不是因?yàn)?PHP 8.1 版本造成的,版本更改只是讓它們(再次)出現(xiàn),有時(shí)我什至?xí)ㄟ^維護(hù) PHP 版本來獲得完整的錯(cuò)誤集群作為副漁獲物。

備忘單

  • #(string)$mixed - 之前的行為
  • $mixed ?? '' - 僅在 null 上抑制 TypeError 錯(cuò)誤
  • @ - 完全錯(cuò)誤抑制。您應(yīng)該在適用的地方記錄您的程式碼庫。
  • @@ - 如果發(fā)生這種情況,這可能是一個(gè)值得研究的有趣地方。
  • 空($mixed)? '' : xxx($mixed) - 把垃圾帶出去,典型的空癱/混合混亂,尋找集群,有機(jī)會(huì)大大簡化程式碼庫。遷移到標(biāo)量類型(PHP 7),從最內(nèi)向外引入嚴(yán)格的類型處理,在適用的情況下使用 PHP「經(jīng)典」和「嚴(yán)格」類型處理。 PHP 7.0 斷言和 PHP 8.1 棄用訊息可以很好地支援這裡。

錯(cuò)誤處理程序

#

錯(cuò)誤處理沒有什麼魔力,它是PHP.net 上記錄的標(biāo)準(zhǔn)(與Example #1),它作為錯(cuò)誤事件的觀察者,可以區(qū)分受抑制的錯(cuò)誤和非受抑制的錯(cuò)誤透過error_reporting(php) / error_reporting(php-ini) 至少達(dá)到通常需要的級(jí)別,如果需要區(qū)分(在生產(chǎn)環(huán)境中,E_DEPRECATED 通常不是報(bào)告的一部分)。此示例性處理程序會(huì)拋出所有報(bào)告的錯(cuò)誤,對(duì)於棄用事件以及E_ALL 也會(huì)拋出此類錯(cuò)誤,因此需要@ 抑制運(yùn)算符不拋出:

set_error_handler(static function ($type, $message, $file, $line) use (&$deprecations) {
    if (!(error_reporting() & $type)) {
        // This error code is not included in error_reporting, so let it fall
        // through to the standard PHP error handler

        // capture E_DEPRECATED
        if ($type === E_DEPRECATED) {
            $deprecations[] =
                ['deprecations' => count($deprecations ?: [])]
                + get_defined_vars();
        }

        return false;
    }

    // throwing error handler, stand-in for own error reporter
    // which may also be `return false;`
    throw new ErrorException($message, $type, error_reporting(), $file, $line);
});

類似的錯(cuò)誤處理程序可以在 3v4l.org 上的擴(kuò)充範(fàn)例中找到,包括要報(bào)告的已棄用程式碼上。

E_USER_DEPRECATED

#從技術(shù)上講,錯(cuò)誤抑制運(yùn)算子可以與 E_USER_DEPRECATED 結(jié)合使用,與上面 E_DEPRECATED 概述的相同。

但是,對(duì)它的控制較少它可能已被專案依賴項(xiàng)中已有的第三方程式碼使用。類似下面的程式碼並不罕見:

@trigger_error('this. a message.', E_USER_DEPRECATED);

它的作用完全相同:發(fā)出棄用事件,但將它們從 PHP 報(bào)告中排除。訂閱這些內(nèi)容可能會(huì)讓您陷入噪音之中。使用 E_DEPRECATED,您總是可以直接從 PHP 獲得「好的、原創(chuàng)的」。


  1. 當(dāng)考慮使用@ 錯(cuò)誤抑制運(yùn)算符的方法並對(duì)其進(jìn)行評(píng)論時(shí),IMSoP 立即舉起紅/黑旗(正確?。苋菀讓雰号c洗澡水一起倒掉@ 抑制運(yùn)算子。在我的回答中,它的目的只是抑制棄用通知但是使用的結(jié)果是它抑制所有診斷訊息和錯(cuò)誤,在某些PHP 版本中甚至是致命的訊息和錯(cuò)誤,因此PHP 退出255,無需任何進(jìn)一步的診斷- 不僅要小心,還要處理。這個(gè)運(yùn)營商很強(qiáng)大。追蹤它在程式碼庫中的使用情況並不斷檢查它是否符合您的基線/期望。對(duì)於合法情況,請(qǐng)考慮使用消音器。為了移植/維護(hù)程式碼,首先使用它來標(biāo)記。完成批量編輯後,再次將其刪除。
P粉592085423

首先,要記住兩件事:

  1. PHP 8.1 棄用這些調(diào)用,它不會(huì)使它們出錯(cuò)。棄用的目的是提前通知作者修復(fù)他們的程式碼,因此您和您使用的程式庫的作者可以在 PHP 9.0 發(fā)布之前修復(fù)問題。因此,不要驚慌,因?yàn)閬K非所有問題都能立即修復(fù),並對(duì)庫維護(hù)人員保持耐心,他們會(huì)在自己的時(shí)間解決這個(gè)問題。
  2. 大多數(shù)情況下的快速解決方法是使用 空合併運(yùn)算子來提供適當(dāng)?shù)念A(yù)設(shè)值,因此您不需要在每次使用時(shí)進(jìn)行長時(shí)間的空檢查。例如,htmlspecialchars($something) 可以替換為 htmlspecialchars($something ?? '')

接下來,一些選項(xiàng):

  • 根據(jù)您的案例數(shù)量,您也許可以一次手動(dòng)修復(fù)幾個(gè)問題,或者添加 ?? '' 或修復(fù)一個(gè)邏輯錯(cuò)誤,無論如何你都不希望出現(xiàn) null。
  • 建立 nullable_htmlspecialchars 等自訂函數(shù),並在程式碼中直接尋找和取代。
  • 建立自訂命名空間函數(shù),例如 nullableoverride\htmlspecialchars;然後在新增 use function nullableoverride\htmlspecialchars; 的任何檔案中,將使用該函數(shù)而不是內(nèi)建函數(shù)。不過,這必須添加到每個(gè)文件中,因此您可能需要一個(gè)工具來自動(dòng)添加它。
  • 使用Rector自動(dòng)新增?? '' 到適當(dāng)?shù)暮瘮?shù)調(diào)用,因此您不必手動(dòng)編輯它們。不幸的是,似乎還沒有這方面的內(nèi)建規(guī)則,因此您必須學(xué)會(huì)編寫自己的規(guī)則。
  • 可能更簡單,根據(jù)您的技能,使用正規(guī)表示式尋找和替換來新增 ?? ''到簡單的情況。
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板