簡體   English   中英

PHP7中對象數組的函數返回類型提示

[英]Function return type hinting for an array of objects in PHP7

我對 PHP 7 中的新功能非常滿意。但我對如何在 PHP 7 中返回對象數組感到困惑。

例如,我們有一個類Item ,我們想從我們的函數中返回這個類的一個對象數組:

function getItems() : Item[] {
}

但它不是這樣工作的。

您可以使用docblocks以這種方式輸入提示。

PhpStorm這樣的 PHP 編輯器 (IDE) 非常支持這一點,並且在迭代此類數組時將正確解析該類。

/**
 * @return YourClass[]
 */
public function getObjects(): array

PHPStorm 還支持嵌套數組:

/**
 * @return YourClass[][]
 */
public function getObjects(): array

較新版本的 PHPStorm 支持 phpstan/psalm 格式:

/**
 * @return array<int, YourObject>
 */
public function getObjects(): array

我實際上理解你的意思,但不幸的是,答案是你不能那樣做。 PHP7 缺乏這種表達能力,因此您可以聲明您的函數以返回“數組”(一個通用數組),或者您必須創建一個新的 ItemArray 類,它是一個 Item 數組(但這意味着您必須自己編寫代碼)。

目前沒有辦法表達“我想要一個項目數組”實例。

編輯:作為補充參考,這里是您想要做的“一系列”RFC ,由於各種原因,它已被拒絕。

當前版本的 PHP 不支持對象數組的內置類型提示,因為沒有像“對象數組”這樣的數據類型。 在某些上下文中,類名可以解釋為類型,也可以解釋為array ,但不能同時解釋為兩者。

實際上,您可以通過創建基於ArrayAccess接口的類來實現這種嚴格的類型提示,例如:

class Item
{
    protected $value;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

class ItemsArray implements ArrayAccess
{
    private $container = [];

    public function offsetSet($offset, $value)
    {
        if (!$value instanceof Item) {
            throw new Exception('value must be an instance of Item');
        }

        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}


function getItems() : ItemsArray
{
    $items = new ItemsArray();
    $items[0] = new Item(0);
    $items[1] = new Item(2);
    return $items;
}

var_dump((array)getItems());

輸出

array(2) {
  ["ItemsArrayitems"]=>
  array(0) {
  }
  ["container"]=>
  array(2) {
    [0]=>
    object(Item)#2 (1) {
      ["value":protected]=>
      int(0)
    }
    [1]=>
    object(Item)#3 (1) {
      ["value":protected]=>
      int(2)
    }
  }
}

目前是不可能的。 但是您可以使用自定義數組類來實現您的預​​期行為


function getItems() : ItemArray {
  $items = new ItemArray();
  $items[] = new Item();
  return $items;
}

class ItemArray extends \ArrayObject {
    public function offsetSet($key, $val) {
        if ($val instanceof Item) {
            return parent::offsetSet($key, $val);
        }
        throw new \InvalidArgumentException('Value must be an Item');
    }
}

感謝主教在這里的回答

我相信這就是你要找的

<?php
class C {}

function objects()
{
    return array (new C, new C, new C);
}
list ($obj1, $obj2, $obj3) = objects();

var_dump($obj1);
var_dump($obj2);
var_dump($obj3);
?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM