Старый пост, но вариативные функции и распаковка массивов могут использоваться (с некоторыми ограничениями) для выполнения хинтинга типизированных массивов, по крайней мере, с PHP7. (На более ранних версиях не тестировал).
Пример:
class Foo {
public function test(){
echo "foo";
}
};
class Bar extends Foo {
//override parent method
public function test(){
echo "bar";
}
}
function test(Foo ...$params){
foreach($params as $param){
$param->test();
}
}
$f = new Foo();
$b = new Bar();
$arrayOfFoo = [$f,$b];
test(...$arrayOfFoo);
//will output "foobar"
Ограничения:
Технически это не решение, так как на самом деле вы не передаете типизированный массив. Вместо этого вы используете оператор распаковки массива 1 ("..." в вызове функции) для преобразования вашего массива в список параметров, каждый из которых должен быть типа, указанного в вариативном объявлении 2 (в котором также используется многоточие).
Знак «...» в вызове функции абсолютно необходим (что неудивительно, учитывая вышесказанное). Пытаюсь позвонить
test($arrayOfFoo)
в контексте приведенного выше примера приведет к ошибке типа, поскольку компилятор ожидает параметр (ы) foo, а не массив. См. Ниже, хотя и хакерское, решение для прямой передачи массива заданного типа с сохранением некоторой подсказки типа.
Функции с переменным числом аргументов могут иметь только один параметр с переменным числом аргументов, и он должен быть последним параметром (иначе как компилятор мог бы определить, где заканчивается параметр с переменным числом аргументов и начинается следующий), что означает, что вы не можете объявлять функции по строкам
function test(Foo ...$foos, Bar ...$bars){
//...
}
or
function test(Foo ...$foos, Bar $bar){
//...
}
Альтернатива "немного лучше, чем просто проверка каждого элемента":
Следующая процедура лучше, чем просто проверка типа каждого элемента, поскольку (1) она гарантирует, что параметры, используемые в функциональном теле, имеют правильный тип, не загромождая функцию проверками типа, и (2 ) он выбрасывает исключения обычного типа.
Учитывать:
function alt(Array $foos){
return (function(Foo ...$fooParams){
//treat as regular function body
foreach($fooParams as $foo){
$foo->test();
}
})(...$foos);
}
Идея состоит в том, чтобы определить и вернуть результат немедленно вызванного закрытия, которое позаботится обо всех вариациях / распаковке за вас. (Можно было бы расширить принцип дальше, определив функцию более высокого порядка, которая генерирует функции этой структуры, уменьшив шаблон). В приведенном выше примере:
alt($arrayOfFoo) // also outputs "foobar"
Проблемы с этим подходом включают:
(1) Это может быть непонятно, особенно неопытным разработчикам.
(2) Это может повлиять на производительность.
(3) Он, как и внутренняя проверка элементов массива, рассматривает проверку типа как деталь реализации, поскольку нужно проверить объявление функции (или воспользоваться исключениями типов), чтобы понять, что только специально типизированный массив является допустимым параметром. В интерфейсе или абстрактной функции невозможно закодировать полную подсказку типа; все, что можно было сделать, это прокомментировать, что ожидается реализация указанного выше вида (или чего-то подобного).
Примечания
[1]. В двух словах: распаковка массива эквивалентна рендерингу
example_function($a,$b,$c);
и
example_function(...[$a,$b,$c]);
[2]. В двух словах: вариативные функции формы
function example_function(Foo ...$bar){
//...
}
можно корректно вызвать любым из следующих способов:
example_function();
example_function(new Foo());
example_function(new Foo(), new Foo());
example_function(new Foo(), new Foo(), new Foo());
//and so on
person
Evan
schedule
28.08.2016
function getFoo($f) { ... }
. Поэтому, если вы хотите иметь функцию, которая обрабатывает исключительно массивы, просто создайте новую функциюfunction getFooArray($f) { ... }
- person sjagr   schedule 24.12.2013function getFoos(Array $f)
, который анализирует массив и передает каждый$f[$i]
вfunction getFoo(Foo $g)
- person Frank Conry   schedule 24.12.2013function foo(Abc ...$args) { } foo(...$arr);
, найденном здесь - person Shahid   schedule 10.06.2016