[英]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.