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

Rob*_*nto 41 php php-7

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

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

function getItems() : Item[] {
}
Run Code Online (Sandbox Code Playgroud)

但它不会这样.

Joh*_*nny 44

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

目前无法表达"我想要一个项目数组"实例.

编辑:作为一个额外的参考,这里是您想要做的"阵列"RFC,由于各种原因它已被拒绝.

  • 我认为转移到PHP 7可以帮助我创建一个严格的输入代码:/ (4认同)
  • 该 RFC 也很古老,是为 php5.6 提出的。我认为他们应该重新考虑它,现在我们都在朝着严格打字的方向发展,它比最初提出时更有意义。 (3认同)
  • 目前我们只能使用实现 ArrayAccess 和 Iterator 接口的自定义类以及一些自定义输入验证。此外 RFC 是 2014 年的,应该重新审视。这将是类型化数组的又一步。就像Java中的String[]、int[]。 (2认同)

emi*_*mix 31

这被称为泛型,遗憾的是我们不会很快看到这个功能.您可以使用docblocks以这种方式键入提示.

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

/**
 * @return YourClass[]
 */
public function getObjects(): iterable
Run Code Online (Sandbox Code Playgroud)

PHPStorm还支持嵌套数组:

/**
 * @return YourClass[][]
 */
public function getObjects(): iterable
Run Code Online (Sandbox Code Playgroud)

  • 除了 PhpStorm,我不会使用其他任何东西。 (5认同)
  • 虽然我赞成你“使用 phpdocs”,但这与 >Generics< 无关。由于泛型的主要原则是“稍后将指定类型,现在使用泛型符号代替真实类型”。在此所述的愿望中,类型在编写代码时是已知的。 (3认同)
  • 是的,也由 phpactor 支持 (2认同)
  • 也适用于 NetBeans。 (2认同)
  • 仅供参考,这不适用于 VSCode + Intelliphense 扩展 (2认同)

Rus*_*nov 7

当前版本的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());
Run Code Online (Sandbox Code Playgroud)

产量

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)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)