2015-12-14 92 views
29

也許我錯過了一些東西,但有沒有任何選項來定義該函數應該有參數或返回例如數組User對象?在PHP 7中鍵入提示 - 對象數組

考慮下面的代碼:

<?php 

class User 
{ 
    protected $name; 

    protected $age; 

    /** 
    * User constructor. 
    * 
    * @param $name 
    */ 
    public function __construct(string $name, int $age) 
    { 
     $this->name = $name; 
     $this->age = $age; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getName() : string 
    { 
     return $this->name; 
    } 

    public function getAge() : int 
    { 
     return $this->age; 
    } 
} 

function findUserByAge(int $age, array $users) : array 
{ 
    $result = []; 
    foreach ($users as $user) { 
     if ($user->getAge() == $age) { 
      if ($user->getName() == 'John') { 
       // complicated code here 
       $result[] = $user->getName(); // bug 
      } else { 
       $result[] = $user; 
      } 
     } 
    } 

    return $result; 
} 

$users = [ 
    new User('John', 15), 
    new User('Daniel', 25), 
    new User('Michael', 15), 
]; 

$matches = findUserByAge(15, $users); 

foreach ($matches as $user) { 
    echo $user->getName() . ' '.$user->getAge() . "\n"; 
} 

是否有任何PHP7選項告知功能findUserByAge應返回用戶的陣列?我期望在添加類型提示時它應該是可能的,但我還沒有找到任何類型的提示信息,因此可能它沒有包含在PHP 7中。如果沒有包含它,你是否有任何線索爲什麼它是在添加類型提示時不包括在內?

+3

只能按照慣例,例如在DocBlock中使用'@return User []' – Gordon

回答

50

它不包括在內。

如果沒有包含它,你有沒有任何線索爲什麼它不包括在添加類型提示時?

對於當前的數組實現,它需要在運行時檢查所有數組元素,因爲數組本身不包含任何類型信息。

它實際上已經提出了PHP 5.6,但被拒絕了:RFC "arrayof" - 有趣的是,這並不是因爲性能問題變得微不足道,而是因爲在應該如何實施方面沒有達成一致。也有人反對說,如果沒有標量類型提示,它是不完整的。如果您對整個討論感興趣,請閱讀in the mailing list archive

恕我直言,陣列類型提示將提供與類型數組最大的好處,我很樂意看到他們實施。

所以也許是時候換一個新的RFC並重新開始討論了。


部分解決方法:

您可以鍵入提示可變參數,從而寫入簽名

function findUserByAge(int $age, User ...$users) : array 

用法:

findUserByAge(15, ...$userInput); 

在這個調用,參數$userInput會被「解壓縮」成單個變量,並且在方法本身「打包」回到一個n陣列$users。每個項目被驗證爲User類型。 $userInput也可以是一個迭代器,它會被轉換爲一個數組。

不幸的是,對於返回類型沒有類似的解決方法,您只能將它用於最後一個參數。

+0

7.1怎麼樣? –

+0

@RobertLimanto否,並且仍然沒有看到7.2,看看https://wiki.php.net/rfc#php_next_72 –

+0

我很想看到一種方法來指定哪種類型在返回的數組中。我認爲這對於IDE來說很好,因爲它可以讓他們理解類型,從而爲自動完成等提供更好的支持。另外,更強大的類型暗示,雖然有可能不指定類型,但感覺像是一個很好的組合。 – Icarus

6

由於數組可以包含混合值,所以這是不可能的。

你必須爲此目的使用一個對象/類。

您可以創建一個管理自己的列表數組(私有/受保護的屬性)的類,並拒絕將其他值作爲此問題的工作週期添加,如果真的需要的話。

但是,沒有負責任的程序員會打破預期的模式,特別是如果你正確地評論它。無論如何,它會在程序中發生錯誤時識別出來。

的exaplanation:

例如可以創建任何數組:

$myArray = array(); 

,並添加了一些:

$myArray[] = 1; 

的字符串:

$myArray[] = "abc123"; 

和對象

$myArray[] = new MyClass("some parameter", "and one more"); 

另外不要忘記,你可以有一個簡單的數組,多維堆疊數組,也可以有混合模式的關聯數組。

直到不​​可能找到一個解析器/ nottation來使所有版本都可以使用強制數組格式的表達式。

這將是很酷的一面,但在勳章的另一面,你會失去一些數組混合數據的能力,這可能對現有代碼和PHP的靈活性提供很大的關鍵性。

由於PHP 7中我們不想錯過的混合內容,所以不可能輸入數組的確切內容,因爲您可以放入任何內容。

2

加上Steini的回答。

您可以創建,管理您的ObjectN並實現一個Iterator類ObjectNIterator:http://php.net/manual/en/class.iterator.php

從methodN,稱之爲還給填充的ObjectNIterator的classMethodM然後將該數據傳遞給需要ObjectNIterator一個methodO:

public function methodO(ObjectNIterator $objectNCollection)

+0

是的,我在PHP 5.x上也完全一樣,但是使用PHPDoc類型的提示,它由PhpStorm IDE使用(它很好地顯示了所有可能的問題)。我有一個對象關係映射器,它根據聲明式XML規範(與模型之間)生成這些類型化的迭代器類(數組),所以我沒有問題很快創建它們。將PHP轉換成強類型語言會很好。 –