Тип намека на PHP 7 – массив объектов

Может быть, я что-то пропустил, но есть ли возможность определить, что функция должна иметь аргумент или возвращать массив массива объектов User?

Рассмотрим следующий код:

<?php class User { protected $name; protected $age; /** * User constructor. * * @param $name */ public function __construct(string $name, int $age) { $this->name = $name; $this->age = $age; } /** * @return mixed */ public function getName() : string { return $this->name; } public function getAge() : int { return $this->age; } } function findUserByAge(int $age, array $users) : array { $result = []; foreach ($users as $user) { if ($user->getAge() == $age) { if ($user->getName() == 'John') { // complicated code here $result[] = $user->getName(); // bug } else { $result[] = $user; } } } return $result; } $users = [ new User('John', 15), new User('Daniel', 25), new User('Michael', 15), ]; $matches = findUserByAge(15, $users); foreach ($matches as $user) { echo $user->getName() . ' '.$user->getAge() . "\n"; } 

Есть ли какой-либо вариант в PHP7, чтобы сказать, что функция findUserByAge должна возвращать массив пользователей? Я ожидал бы, что при добавлении типа hinting это должно быть возможно, но я не нашел никакой информации для типа hinting для массива объектов, поэтому, вероятно, он не включен в PHP 7. Если он не включен, есть ли у вас какие-либо подсказки, почему это было не включается при добавлении типа hinting?

Это не включено.

Если он не включен, есть ли у вас какие-либо подсказки, почему он не был включен, когда был добавлен тип намека?

При реализации текущего массива потребуется проверка всех элементов массива во время выполнения, поскольку сам массив не содержит информации о типе.

Это уже было предложено для PHP 5.6, но отклонено: RFC «arrayof» – интересно не из-за проблем с производительностью, которые оказались небрежными, а потому, что не было договоренности о том, как именно это должно быть реализовано. Было также возражение, что оно является неполным без подсказок скалярного типа. Если вас интересует вся дискуссия, прочитайте ее в архиве списка рассылки .

Подсказки типа массива IMHO обеспечили бы большую выгоду вместе с типизированными массивами, и мне было бы приятно их реализовать.

Возможно, пришло время для нового RFC и возобновить эту дискуссию.


Частичное обходное решение:

вы можете вводить вариативные аргументы и, таким образом, записывать подпись как

 function findUserByAge(int $age, User ...$users) : array 

Применение:

 findUserByAge(15, ...$userInput); 

В этом вызове аргумент $userInput будет «распакован» в отдельные переменные, а в самом методе «упакован» обратно в массив $users . Каждый элемент проверяется на тип User . $userInput также может быть итератором, он будет преобразован в массив.

К сожалению, для возвращаемых типов не существует аналогичного метода обхода, и вы можете использовать его только для последнего аргумента.

Поскольку массивы могут содержать смешанные значения, это невозможно.

Для этого вам нужно использовать объекты / класс.

Вы можете создать класс, который будет управлять собственным массивом списка (частный / защищенный атрибут) и запретить добавлять другие значения в качестве рабочего стола для этой проблемы, если это действительно необходимо.

Однако ни один ответственный программист никогда не нарушит намеченный шаблон, особенно если вы его правильно прокомментируете. В любом случае, это будет признано во всех ошибках программы.

Экзарализация:

Например, вы можете создать любой массив:

 $myArray = array(); 

и добавьте число:

 $myArray[] = 1; 

строка:

 $myArray[] = "abc123"; 

и объект

 $myArray[] = new MyClass("some parameter", "and one more"); 

Также не забывайте, что у вас может быть простой массив, многомерный многоуровневый массив, а также ассоциативные массивы, которые также могут иметь смешанные шаблоны.

Его довольно трудно, пока невозможно найти парсер / nottation, чтобы все версии работали с выражением, которое заставляет формат для массива, я думаю.

Было бы здорово с одной стороны, но с другой стороны медали вы потеряете некоторую способность смешать данные в массиве, которые могут иметь решающее значение для большого количества существующего кода и гибкости PHP.

Из-за смешанного контента, функции которого мы не хотим пропустить в PHP 7, невозможно набрать точное совпадение массива, как вы можете что-то вставить.

Добавляя к тому, что ответил Штеини.

Вы можете создать класс ObjectNIterator, который управляет вашим ObjectN и реализует Iterator: http://php.net/manual/en/class.iterator.php

Из методаN вызовите классMethodM, который возвращает заполненный ObjectNIterator, затем передайте эти данные методуO, который ожидает ObjectNIterator:

public function methodO(ObjectNIterator $objectNCollection)