Это один из тех вопросов новичков, на который нельзя давать прямой ответ. Он превратится в пустое умствование и говнокод. Соглашусь с комментарием
Дмитрий: тут просто не нужен массив. И тем более не нужно городить огород из абстракций. Тут явно нужен банальный VO/DTO, а автору надо перестать пытаться заворачивать привычные массивы в солидно выглядящие объекты, и начать использовать сами объекты.
Если нам нужна конкретная структура, то и описываем её в конкретном классе,
безо всяких интерфейсов:
final readonly class Parameters
{
public function __construct(
public string $key1,
public int $key2,
public DateTimeImmutable $key3,
) {}
}
public function execute(Parameters $parameters):
В итоге у "стороннего разработчика" есть готовая документация - простое и понятное определение класса, экземпляр которого он должен передать в ваш метод. И уже на этапе создания этого объекта РНР надаёт разработчику по рукам, если хоть какое-то свойство не будет задано, или будет не того типа. При желании можно в конструктор добавить дополнительную валидацию, если просто типа недостаточно.
При этом если внутри execute() вдруг зачем-то понадобится обратиться к свойствам именно как к массиву, то использовать волшебную функцию
get_object_vars()
.
Если же речь про валидацию входящих данных, то это вообще совсем другой вопрос.
Для этого есть либо стандартные
валидаторы, когда на вход подаётся массив и набор правил, вот например как в
ларавле,
симфони или в десятке отдельно стоящих
библиотек, а на выходе - или гарантированно валидная структура данных, или ошибка.
Либо готовые
библиотеки десериализации, когда входящий JSON автоматом мапится на существующий объект, и в итоге получается или либо гарантированно валидный объект, или ошибка.
В этом случае документацией для обоих вариантов является сваггер, а фидбеком - ошибки валидатора.