首頁 > 後端開發 > php教程 > 在PHP中創建嚴格鍵入的數組和收集

在PHP中創建嚴格鍵入的數組和收集

Christopher Nolan
發布: 2025-02-10 11:20:11
原創
163 人瀏覽過

在PHP中創建嚴格鍵入的數組和收集

鑰匙要點

    php 5.6引入了使用…代幣創建鍵入數組的能力,該功能或方法表示函數或方法接受可變的參數長度。可以將此功能與類型提示結合在一起,以確保僅在數組中接受某些類型的對象。
  • >此功能的一個限制是,每個方法只能定義一個鍵入的數組。為了克服這一點,可以將鍵入的數組注入“集合”類中,這也允許比Get Methods上的“數組”更具體的返回類型。
  • 值對象可用於自定義驗證。例如,可以使用約束來創建一個評分值對象,以確保評級始終在0到5之間。這提供了單個收集成員的其他驗證,而無需循環每個注入的對象。 >
  • >嚴格鍵入的陣列和集合具有多個優點。它們在一個地方提供了簡單的類型驗證,確保在構造時始終對值進行驗證,允許每個集合添加自定義邏輯,並減少在方法簽名中混合參數的機率。
  • >可以添加方法以促進初始構造後的收集和價值對象的值進行編輯,但是在需要進行更改時,將它們保持不變並將其轉換為原始類型是更有效的。進行更改後,可以使用更新的值重建集合或值對象,然後將再次驗證。
  • >
  • 這篇文章首先出現在媒介上,並在作者的許可下重新發布。我們鼓勵您在Medium上關注Bert,並在那裡給他一些喜歡!
>在PHP 5.6中宣布的語言功能之一是添加...代幣來表示函數或方法接受可變的參數。

我很少提到的東西是,可以將此功能與類型提示結合起來,從而基本上創建了鍵入的數組。 > 例如,我們可以擁有一個電影類,其中一個方法可以設置一個僅接受dateTimeImmutable對象的空氣日期。


我們現在可以將可變數量的單獨的dateTimeImmutable對像傳遞給setairdates()方法:>

如果我們要通過dateTimeImmutable以外的其他內容,例如,將丟棄致命錯誤:

>

<span><span><?php
</span></span><span>
</span><span><span>class Movie {  
</span></span><span>  <span>private $dates = [];
</span></span><span>
</span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
</span></span><span>    <span>$this->dates = $dates;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAirDates() {
</span></span><span>    <span>return $this->dates;
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
登入後複製
登入後複製
登入後複製
登入後複製
>如果我們已經有一系列DateTimeImmutable對象,我們想將其傳遞給SetairDates(),我們可以再次使用...

>數組包含一個不是預期類型的​​值,我們仍然會遇到前面提到的致命錯誤。

>此外,我們可以從php 7開始使用標量類型。

再次,這可以確保評級屬性將始終包含浮子,而無需我們在所有內容上循環以驗證它們。因此,現在我們可以在getaveragerating()中輕鬆地對它們進行一些數學操作,而不必擔心無效的類型。
<span><span><?php
</span></span><span>
</span><span><span>class Movie {  
</span></span><span>  <span>private $dates = [];
</span></span><span>
</span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
</span></span><span>    <span>$this->dates = $dates;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAirDates() {
</span></span><span>    <span>return $this->dates;
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
登入後複製
登入後複製
登入後複製
登入後複製
> 這種打字數組的問題

>使用此功能作為鍵入數組的缺點之一是,我們只能定義每個方法的一個這樣的數組。假設我們希望有一個電影類,該班級期望空氣日期列表以及構造函數中的評分列表,而不是以後通過可選方法設置它們。上面使用的方法是不可能的。

>

>另一個問題是,當使用PHP 7時,我們的get()方法的返回類型仍然必須是“數組”,這通常太通用了。

>

解決方案:集合類

要解決這兩個問題,我們可以簡單地將我們的鍵入數組注入所謂的“收集”類中。這也改善了我們的關注點,因為我們現在可以將平均評級的計算方法移至相關集合類別:>

>請注意,我們仍在使用構造函數中具有可變長度的鍵入參數列表,這為我們節省了在每個評分上循環以檢查其類型的麻煩。 >

如果我們希望能夠在foreach循環中使用此集合類,我們只需要實現iteratorAggregate界面:>

<span><span><?php
</span></span><span>
</span><span><span>$movie = new Movie();
</span></span><span>
</span><span><span>$movie->setAirDates(
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'),
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22')
</span></span><span><span>);
</span></span>
登入後複製
>繼續前進,我們還可以為我們的空氣日期列表創建一個集合:>

在電影類中將所有難題的所有部分都放在一起,我們現在可以在構造函數中註入兩個單獨鍵入的集合。此外,我們可以在GET方法上定義比“數組”更具體的返回類型:>

使用自定義驗證的值對象

<span><span><?php
</span></span><span>
</span><span><span>$dates = [
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'),
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22'),
</span></span><span><span>];
</span></span><span>
</span><span><span>$movie = new Movie();
</span></span><span><span>$movie->setAirDates(...$dates);
</span></span>
登入後複製
>如果我們想在評分中添加額外的驗證,我們仍然可以進一步走一步,並使用一些自定義約束定義評級值對象。例如,額定值可能受到0至5之間的限制:

>回到我們的評分收集類中,我們只需要進行一些較小的更改即
<span><span><?php
</span></span><span>
</span><span><span>declare(strict_types=1);
</span></span><span>
</span><span><span>class Movie {
</span></span><span>  <span>private $dates = [];
</span></span><span>  <span>private $ratings = [];
</span></span><span>
</span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) { /* ... */ }
</span></span><span>  <span>public function getAirDates() : array { /* ... */ }
</span></span><span>
</span><span>  <span>public function setRatings(float ...$ratings) {
</span></span><span>    <span>$this->ratings = $ratings;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAverageRating() : float {
</span></span><span>    <span>if (empty($this->ratings)) {
</span></span><span>      <span>return 0;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$total = 0;
</span></span><span>
</span><span>    <span>foreach ($this->ratings as $rating) {
</span></span><span>      <span>$total += $rating;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>return $total / count($this->ratings);
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
登入後複製

這樣,我們將獲得對單個收集成員的其他驗證,但仍然不必循環每個注入的對象。

<span><span><?php
</span></span><span>
</span><span><span>declare(strict_types=1);
</span></span><span>
</span><span><span>class Ratings {
</span></span><span>  <span>private $ratings;
</span></span><span>
</span><span>  <span>public function __construct(float ...$ratings) {
</span></span><span>    <span>$this->ratings = $ratings;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAverage() : float {
</span></span><span>    <span>if (empty($this->ratings)) {
</span></span><span>      <span>return 0;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$total = 0;
</span></span><span>
</span><span>    <span>foreach ($this->ratings as $rating) {
</span></span><span>      <span>$total += $rating;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>return $total / count($this->ratings);
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
登入後複製
優點

鍵入這些單獨的收集類和值對像似乎很重要,但是它們比通用數組和標量值具有多個優點:

>

<span><span><?php
</span></span><span>
</span><span><span>declare(strict_types=1);
</span></span><span>
</span><span><span>class Ratings implements IteratorAggregate {
</span></span><span>  <span>private $ratings;
</span></span><span>
</span><span>  <span>public function __construct(float ...$ratings) {
</span></span><span>    <span>$this->ratings = $ratings;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAverage() : float { /* ... */ }
</span></span><span>
</span><span>  <span>public function getIterator() {
</span></span><span>     <span>return new ArrayIterator($this->ratings);
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
登入後複製
>

在一個地方輕鬆類型驗證。我們永遠不必手動循環瀏覽一個數組來驗證我們的收集成員的類型; > 在應用程序中,無論我們在何處使用這些集合和價值對象,我們都知道它們的價值在構造時始終得到驗證。例如,任何評分始終在0和5之間;

  • >

  • 我們可以輕鬆地添加每個集合和/或值對象的自定義邏輯。例如,我們可以在整個應用程序中重新使用getaverage()方法
  • >

    >
  • 我們有可能在單個函數或方法中註入多個鍵入列表,我們不能使用... doken來做,而無需先註入集合類中的值;
  • > 在方法簽名中混合參數的機率大大減少。例如,當我們要注入評級列表和空氣日期列表時,兩者在使用通用陣列時很容易被偶然地混在一起;
  • 編輯呢?

    到目前

    >我們可以添加方法來促進編輯,但這很快就會變得麻煩,因為我們必須在每個集合上複製大多數方法,以保持類型提示的優勢。例如,評分上的add()方法僅應接受評級對象,而airdates上的add()方法只能接受dateTimeMutable對象。這使得這些方法的接口和/或重複使用非常困難。
  • > 相反,我們可以簡單地保留我們的收集和重視對像不可變的,並在需要進行更改時將它們轉換為原始類型。完成更改後,我們可以簡單地重建具有更新值的任何必要的集合或值對象。在(重新)構造後,所有類型都將再次驗證,以及我們可能定義的任何額外驗證。 例如,我們可以在收藏中添加一個簡單的toarray()方法,然後進行這樣的更改:>

    這樣,我們也可以重新使用現有數組功能,例如array_filter()。

    >如果我們確實需要對收集對象進行編輯,則可以在需要的任何地方添加必要的方法。但是請記住,其中大多數也必須對給定參數進行類型驗證,因此很難在所有不同的集合類中重新使用它們。

    重複使用通用方法

    >您可能已經註意到,通過在所有這些中實現ToArray()和GetIterator(),我們仍在在我們的集合課程中獲得一些代碼重複。幸運的是,這些方法足夠通用,可以移至通用父類,因為它們都簡單地返回注入的數組:>

    >我們將在收集類中留下的一切將是構造函數中的類型驗證,以及任何特定於該集合的可選額外邏輯,例如:>
    <span><span><?php
    </span></span><span>
    </span><span><span>class Movie {  
    </span></span><span>  <span>private $dates = [];
    </span></span><span>
    </span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
    </span></span><span>    <span>$this->dates = $dates;
    </span></span><span>  <span>}
    </span></span><span>
    </span><span>  <span>public function getAirDates() {
    </span></span><span>    <span>return $this->dates;
    </span></span><span>  <span>}
    </span></span><span><span>}
    </span></span>
    登入後複製
    登入後複製
    登入後複製
    登入後複製
    >
    <span><span><?php
    </span></span><span>
    </span><span><span>class Movie {  
    </span></span><span>  <span>private $dates = [];
    </span></span><span>
    </span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
    </span></span><span>    <span>$this->dates = $dates;
    </span></span><span>  <span>}
    </span></span><span>
    </span><span>  <span>public function getAirDates() {
    </span></span><span>    <span>return $this->dates;
    </span></span><span>  <span>}
    </span></span><span><span>}
    </span></span>
    登入後複製
    登入後複製
    登入後複製
    登入後複製

    >可選的是,我們可以使我們的集合最終取得最終成績,以防止任何兒童類都以可以消除我們的類型驗證的方式弄亂了屬性。 >

    結論

    >雖然遠非完美,但它穩步地使用php的最新發行版中的集合和價值對像中的類型驗證變得越來越容易。

    >理想情況下,我們將在未來版本的PHP中獲得某種形式的仿製藥,以進一步促進可重複使用的收集類的創建。

    >

    >大大改善價值對象使用的功能將是除字符串之外,還可以將對象施放給不同的原始類型。可以通過添加與__tostring()相當的額外魔法方法來輕鬆實現,例如__toint(),__tofloat()等。

    >幸運的是,正在進行一些RFC,可以在以後的版本中實現這兩個功能,因此手指交叉了! ?

      generics:https://wiki.php.net/rfc/generics
    • 通用數組:https://wiki.php.net/rfc/generic-arrays
    • >

    • 將對象鑄成標量:https://wiki.php.net/rfc/class_casting_to_to_scalar
    • >

    >如果您發現本教程有幫助,請訪問Medium上的原始帖子,並給它一些❤️。如果您有任何反饋,疑問或評論,請在下面或原始帖子上留下回答。
    經常詢問的問題(常見問題解答)有關在PHP

    >中創建嚴格鍵入的數組和收藏

    >在PHP中使用嚴格鍵入數組的好處是什麼好處?這在數據一致性至關重要的較大,更複雜的應用中特別有用。通過為數組中的所有元素執行特定類型,您可以防止由於意外數據類型而可能發生的潛在錯誤和錯誤。這也使您的代碼更容易預測,更易於調試,因為您始終知道您正在使用的數據類型。

    如何在PHP中創建一個嚴格鍵入的數組?不本地支持嚴格鍵入的數組。但是,您可以創建一個類,該類可以對添加到數組中添加的元素進行檢查。此類將具有添加和檢索元素的方法,這些方法將在執行操作之前檢查元素的類型。如果該元素的類型與預期類型不匹配,則會丟棄錯誤。

    我可以使用php?

    中的數組使用類型提示,是的,PHP支持對數組的類型提示。您可以通過在函數或方法聲明中的參數名稱之前添加“數組”來指定函數或方法將數組作為參數的期望。但是,這僅確保參數是數組,而不是數組中的所有元素均為特定類型。

    >鬆散鍵入和嚴格鍵入的數組之間有什麼區別?在嚴格鍵入的數組中,所有元素必須是特定類型的。如果您嘗試在嚴格鍵入的數組中添加其他類型的元素,則將丟棄錯誤。

    >

    >如何執行PHP?

    >

    >您可以強制執行檢查中的檢查PHP通過使用“聲明(strict_types = 1);”;指令在您的PHP文件開始時。這將強制執行嚴格的類型檢查文件中的所有函數調用和返回語句。

    我可以在PHP中創建一個嚴格鍵入的對像數組? PHP中的對象通過創建一個類型的類,該類可以在添加到數組中添加的對像上檢查。該類將具有添加和檢索對象的方法,並且這些方法在執行操作之前會檢查對象的類型。

    php?

    的嚴格鍵入數組的局限性是什麼? PHP中嚴格鍵入數組的主要限制是它們需要其他代碼才能實現,因為PHP並未在本地支持它們。這可以使您的代碼更加複雜和難以維護。此外,嚴格鍵入的數組可以比鬆散鍵入的數組更靈活,因為它們不允許使用不同類型的元素。

    我可以使用php?

    的多維數組的類型提示,是的,是的。您可以使用PHP中的多維陣列使用類型提示。但是,PHP的類型暗示僅確保參數是一個數組,而不是數組(或子陣列)中的所有元素均為特定類型。 php?

    在PHP中使用嚴格鍵入數組時,您可以使用try-catch塊來處理錯誤。如果將元素添加到數組時發生錯誤(例如,如果元素是錯誤的類型),則將拋出異常。您可以捕獲此例外並適當處理。

    我可以使用具有PHP的內置數組函數的嚴格鍵入數組嗎?

    是的,您可以使用PHP的內置陣列使用嚴格鍵入的數組功能。但是,您需要小心,因為這些功能不會強制執行檢查。如果您使用修改數組的函數並添加錯誤類型的元素,則可能會導致錯誤。

    >

    以上是在PHP中創建嚴格鍵入的數組和收集的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    作者最新文章
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板