函数返回类型提示PHP7中的对象数组

时间:2016-11-19 13:30:35

标签: php php-7

我对PHP 7中的新功能非常满意。但是我对如何在PHP 7中返回一个对象数组感到困惑。

例如,我们有一个类Item,我们想从函数中返回该类的对象数组:

function getItems() : Item[] {
}

但它不会这样。

5 个答案:

答案 0 :(得分:38)

我实际上明白你的意思,但不幸的是答案是你无法做到这一点。 PHP7缺乏那种表现力,所以你可以声明你的函数返回" array" (通用数组)或者你必须创建一个新的ItemArray类,它是一个Item数组(但这意味着你必须自己编写代码)。

目前无法表达"我想要一个Item"实例

编辑:作为一个补充参考,这里是您想要做的"array of" RFC,由于各种原因,它已被拒绝。

答案 1 :(得分:22)

这称为Generics,不幸的是我们won't see this feature any time soon。您可以使用docblocks以这种方式键入提示。

PhpStorm这样的PHP编辑器(IDE)非常支持这一点,并且在迭代这样的数组时会正确地解析类。

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

PHPStorm还支持嵌套数组:

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

答案 2 :(得分:6)

当前版本的PHP不支持一个对象数组的内置类型提示,因为没有像#34这样的数据类型;一个对象数组&# 34 ;.类名可以解释为某些上下文中的类型,以及array,但不能同时解释为两种类型。

实际上,你可以通过创建一个基于ArrayAccess接口的类来实现这种严格的类型提示,例如:

class Item {
  protected $value;

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


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

  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)
    }
  }
}

答案 3 :(得分:0)

目前不可能。但是您可以通过自定义数组类实现预期的行为


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');
    }
}

感谢bishop's answer here

答案 4 :(得分:-3)

我相信这就是您要寻找的

<?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);
?>