」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 掌握 PHP:類型提示技術

掌握 PHP:類型提示技術

發佈於2024-11-08
瀏覽:870

Mastering PHP: Type Hinting techniques
照片由? ? ? ???關於 Unsplash

類型提示被一些人認為是功能的聖杯。所有程式語言都必須具備的一種。 PHP 很長一段時間都沒有這樣的系統,但現在已被大多數開發人員廣泛採用。

也就是說,PHP 的型別系統不如其他語言。許多實現了所謂的泛型。這是在結構和集合之間強制執行類型的能力。例如,在 Java 中,我們可以指定陣列必須只包含某種類型的項目,例如字串陣列。

也許有一天我們也會在 PHP 中擁有這個功能,但在那之前我們實際上可以透過一些不同的技術來解決這個問題。由於缺乏更好的描述,我將它們稱為軟類型提示運行時提示

類型提示

第一個也是最明顯的類型提示是 PHP 7 中引入的類型提示,並且仍在添加到 PHP 中。類型提示常數僅在 PHP 8.3 中新增。

類型提示有助於傳達需要作為參數傳遞給方法或函數的內容或該方法將傳回的內容。類型提示將影響它們使用的任何類別的簽名,因為擴展具有已建立的類型提示的類別將意味著它們不能被覆蓋。

充分利用類型的類別的範例是:




當然,我們的類型提示有限制,因為如前所述,我們不能讓陣列全部具有相同的類型,而必須只使用 array 。我們也不能將數字限制為只能是正數或在某個範圍內。

另一種可能是閉包,因為無法在 PHP 的本機類型中描述匿名函數。相反,我們必須使用 \Closure 或 callable 。通常,callable 也不允許用作類型。

幸運的是,仍然有一種方法可以使用類型提示來描述這些更複雜的場景。

軟型提示

我們的下一個類型提示是透過 PHPDocs 提供的。如果傳遞方法或傳回錯誤類型,本機類型將在運行時引發異常,但 PHPDoc 類型提示對應用程式的運行時沒有影響。

相反,軟類型提示純粹是在我們使用 VS Code 或 PHPStorm 等 IDE 時為我們提供幫助,它們會為我們檢測這些類型。另一個用例是使用 PHPStan 和隨後的 Rector 等靜態分析工具。

使用軟類型的最大優點是它可以讓你更精確地描述任何參數、屬性等的類型。例如,我們可以採用前面的類,更容易理解所使用的數組或閉包.




確保所有類型使用正確的最佳方法是安裝 PHPStan。從那裡您可能需要至少使用等級 5。然後可以透過持續整合步驟來檢查類型提示是否正確。

如果您想使用正確的軟類型提示,實際上可以使用一個清單。更好的是,如果您不確定並且想要執行快速測試,可以使用 PHPStan 工具來測試 PHPStan 暗示的所有類型是否正確。

運行時提示

我們支援類型的下一個方法是使用執行時間提示。這實際上意味著執行我們自己的程式碼來檢查參數的類型。例如,我們可以檢查陣列是否只包含特定類型的物件。如果沒有,那麼我們拋出一個 InvalidArgumentException。




順便說一下,這種技巧有時被稱為防禦性程式設計。看看程式碼範例,這相當麻煩。只是為了簡單地檢查數組是否正確而編寫了很多程式碼。這就是為什麼我們經常求助於庫,在本例中是 webmozart/assert .


composer require webmozart/assert


現在安裝了這個軟體包,我們可以將其縮短為簡單的一行。




這個函式庫的一大優點是,如果您在 PHPStan 上新增 Assert 擴展,這將有助於分析程式碼時的類型覆蓋率。

結論

總之,掌握 PHP 中的類型提示對於希望編寫乾淨、可維護且可靠的程式碼的開發人員來說是一項基本技能。雖然 PHP 的類型系統仍然缺乏其他語言中的一些功能,例如泛型,但有多種策略可用於強制執行更嚴格的類型  —  無論是透過本機類型提示、PHPDoc 註釋還是運行時檢查。利用 PHPStan 等工具和 Assert 等函式庫可以幫助您確保類型安全,即使在複雜的場景中也是如此。透過將這些技術整合到您的開發工作流程中,您將能夠更好地自信且精確地處理 PHP 的動態特性。

我是 Peter Fox,一位在英國使用 Laravel 的軟體開發人員。感謝您閱讀我的文章,我還有更多內容可以閱讀 https://articles.peterfox.me。我現在也是 GitHub 上的贊助者。如果您想鼓勵我寫更多這樣的文章,請考慮捐贈一筆小額一次性捐款。

版本聲明 本文轉載於:https://dev.to/peter_fox/mastering-php-type-hinting-techniques-3g8e?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-03-11
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-03-11
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-03-11
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    程式設計 發佈於2025-03-11
  • 為什麼不使用CSS`content'屬性顯示圖像?
    為什麼不使用CSS`content'屬性顯示圖像?
    在Firefox extemers屬性為某些圖像很大,&& && && &&華倍華倍[華氏華倍華氏度]很少見,卻是某些瀏覽屬性很少,尤其是特定於Firefox的某些瀏覽器未能在使用內容屬性引用時未能顯示圖像的情況。這可以在提供的CSS類中看到:。 googlepic { 內容:url(&...
    程式設計 發佈於2025-03-11
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符在postgresql中提取最後一行,您可能需要遇到與數據集合中每個不同標識的信息相關的信息。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: id dat...
    程式設計 發佈於2025-03-11
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-03-11
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-03-11
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-03-11
  • 如何從PHP中的數組中提取隨機元素?
    如何從PHP中的數組中提取隨機元素?
    從陣列中的隨機選擇,可以輕鬆從數組中獲取隨機項目。考慮以下數組:; 從此數組中檢索一個隨機項目,利用array_rand( array_rand()函數從數組返回一個隨機鍵。通過將$項目數組索引使用此鍵,我們可以從數組中訪問一個隨機元素。這種方法為選擇隨機項目提供了一種直接且可靠的方法。
    程式設計 發佈於2025-03-11
  • 為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    mySQL錯誤#1089:錯誤的前綴鍵錯誤descript [#1089-不正確的前綴鍵在嘗試在表中創建一個prefix鍵時會出現。前綴鍵旨在索引字符串列的特定前綴長度長度,可以更快地搜索這些前綴。 了解prefix keys `這將在整個Movie_ID列上創建標準主鍵。主密鑰對於唯一識...
    程式設計 發佈於2025-03-11
  • 可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    程式設計 發佈於2025-03-11
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    在使用GO MOD時,在GO MOD 中克服模塊路徑差異時,可能會遇到衝突,其中3個Party Package將另一個PAXPANCE帶有導入式套件之間的另一個軟件包,並在導入式套件之間導入另一個軟件包。如迴聲消息所證明的那樣: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    程式設計 發佈於2025-03-11
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-03-11

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3