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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40693469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:13:40  来源:igfitidea点击:

Function return type hinting for an array of objects in PHP7

phpphp-7

提问by Robert Limanto

I am very happy with the new features in PHP 7. But I am confused on how to return an array of objects in PHP 7.

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

For example, we have a class Item, and we want to return an array of objects of this class from our function:

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

function getItems() : Item[] {
}

But it does not work this way.

但它不是这样工作的。

采纳答案by Johnny

I actually understand what you mean, but the answer unfortunately is that you can't do that. PHP7 lacks that kind of expressivity, so you can either declare your function to return "array" (a generic array) or you have to create a new class ItemArray which is an array of Item (but that meaning you will have to code it yourself).

我实际上理解您的意思,但不幸的是,您不能这样做。PHP7 缺乏这种表现力,因此您可以声明您的函数以返回“数组”(通用数组),或者您必须创建一个新类 ItemArray,它是一个 Item 数组(但这意味着您必须自己编写代码) )。

There is currently no way to express "I want an array of Item" instances.

目前没有办法表达“我想要一个 Item 数组”实例。

EDIT: As an added reference, here the "array of" RFCof what you wanted to do, it has been declined due to various reasons.

编辑:作为补充参考,这里是您想要做的“数组”RFC,由于各种原因已被拒绝。

回答by emix

This is called Generics, unfortunately we won't see this feature any time soon. You can type hint this way though using docblocks.

这叫做泛型,不幸的是我们不会很快看到这个特性。您可以使用docblocks 以这种方式输入提示。

PHP editor (IDE) like PhpStormsupports this very well and will properly resolve the class when iterating over such array.

PhpStorm这样的PHP 编辑器 (IDE)很好地支持这一点,并且在迭代此类数组时将正确解析该类。

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

PHPStorm also supports nested arrays:

PHPStorm 还支持嵌套数组:

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

回答by Ruslan Osmanov

The current version of PHP doesn't support a built-in type hinting for an array of objects, as there is no such data type as "an array of objects". A class name can be interpreted as a type in certain contexts, as well as array, but not both at a time.

当前版本的 PHP 不支持对象数组的内置类型提示,因为没有“对象数组”这样的数据类型。类名可以在某些上下文中解释为类型,也可以同时解释为array,但不能同时解释为两者。

Actually you can implement such kind of strict type hinting by creating a class based on the ArrayAccessinterface, e.g.:

实际上,您可以通过基于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());

Output

输出

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

回答by safrazik

You can achieve your intended behavior with a custom array class

您可以使用自定义数组类实现预期行为


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

Thanks to bishop's answer here

感谢主教在这里的回答