Declarando estruturas de array em PHP
Infelizmente, não é possível definir tipos de array explícitos como fazem outras linguagens de programação, como Java:
List<User> users = new ArrayList<>();
Esperançosamente, algumas ferramentas como PHPStan ou Psalm nos ajudam a analisar o código estaticamente, o que significa que eles não executam, mas verificam o código em busca de inconsistências com base nos comentários do PHP.
Existem 3 maneiras diferentes de definir o tipo de elementos em um array PHP:
- Maneira herdada:
User[] - Forma da lista:
array<int,mixed>&list<mixed> - Forma do objeto:
array{0:int, foo:?string, bar:mixed}
Esta é uma maneira tradicional de definir uma lista de elementos de um determinado tipo, o problema é que ela se torna ambígua e os clientes que usam esse tipo de lista não conseguem saber se as chaves são inteiros, flutuantes ou strings.
Além disso, os analisadores estáticos não falharão se você tentar obter um elemento por chave com um tipo incorreto; nesses cenários, sugiro usar array<int,mixed>.
No final, quanto mais explícito, melhor.
/** @var User[] $users */
$users = [ ... ];
# Are keys autoincremental integers, random numbers, maybe strings... ?
$firstUser = $users[ ? ];
# Static analyzers won't complain if you use an incorrect type
Usamos listas quando temos um array de elementos com o mesmo tipo.
Para fazer isso, usamos a sintaxe do diamante para declarar os tipos da chave e o valor: array<int,mixed>. Existe um atalho muito útil quando a chave é um inteiro auto-incremental: list<mixed>.
/** @var array<string,User> $users */
$users = [
'jesus' => new User('Jesus Valera'),
'chema' => new User('Chema Valera'),
];
$userJesus = $users['jesus'];
$userChema = $users['chema'];
$users[0]; # ERROR: "Offset 0 does not exist on array<string, User>"
---
/** @var list<User> $users */
$users = [ ... ];
$firstUser = reset($users);
$lastUser = end($users);
Usamos a forma do objeto quando a matriz não é uma coleção de objetos, mas um mapa que contém informações.
Para fazer isso, usamos a sintaxe de colchetes e definimos o nome da chave e o tipo, podemos dividir por vírgulas se houver vários elementos: .array{foo:int, bar:string}
/** @var array{id:int, birthdate: DateTimeImmutable} */
$additionalInfo = [ ... ];
$id = $additionalInfo['id']; # int
$birthdate = $additionalInfo['birthdate']; # DateTimeImmutable
final class User
{
/** @var list<Comment> */
public readonly array $comments;
/** @var array{id:int, birthdate: DateTimeImmutable} */
public readonly array $additionalInfo;
}
Claro, é possível representar qualquer estrutura de array complexa em PHP com esses comentários PHP. Exemplo:
/**
* @var list<
* array{
* uuid?: string,
* content: array{name: string, foo: ?stdClass},
* }
* > $array
*/
$array = [
0 => [
'uuid' => 'XXXX-XXX-XXX-XXXX',
'content' => [
'name' => 'str',
'foo' => null,
],
],
1 => [
'content' => [
'name' => 'str',
'foo' => new stdClass(),
],
],
// ...
];
Recursos:
- Salmo | Formas de Matriz
- PHPStan | Tipos de PHPDoc





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)