Mendeklarasikan struktur array di PHP

Feb 20 2023
Sayangnya, tidak mungkin untuk mendefinisikan tipe array eksplisit seperti bahasa pemrograman lain seperti Java: Semoga, beberapa alat seperti PHPStan atau Psalm membantu kita menganalisis kode secara statis, yang berarti, mereka tidak mengeksekusi tetapi memeriksa kode untuk inkonsistensi berdasarkan pada komentar PHP. Ada 3 cara berbeda untuk mendefinisikan tipe elemen dalam array PHP: Ini adalah cara kuno untuk mendefinisikan daftar elemen dari tipe tertentu, masalahnya menjadi ambigu, dan klien yang menggunakan daftar semacam ini tidak dapat mengetahui apakah kuncinya adalah bilangan bulat, pelampung atau string.

Sayangnya, tidak mungkin untuk mendefinisikan tipe array secara eksplisit seperti yang dilakukan oleh bahasa pemrograman lain seperti Java:

List<User> users = new ArrayList<>();

Mudah-mudahan, beberapa alat seperti PHPStan atau Psalm membantu kita menganalisis kode secara statis, artinya, mereka tidak mengeksekusi tetapi memeriksa kode untuk ketidakkonsistenan berdasarkan komentar PHP.

Ada 3 cara berbeda untuk mendefinisikan tipe elemen dalam array PHP:

  1. Cara warisan:User[]
  2. Bentuk Daftar: array<int,mixed>&list<mixed>
  3. Bentuk Objek:array{0:int, foo:?string, bar:mixed}

Ini adalah cara kuno untuk mendefinisikan daftar elemen dari tipe tertentu, masalahnya menjadi ambigu , dan klien yang menggunakan daftar semacam ini tidak dapat mengetahui apakah kuncinya bilangan bulat, float, atau string.
Selain itu, penganalisis statis tidak akan gagal jika Anda mencoba mendapatkan elemen dengan kunci dengan tipe yang salah, dalam skenario ini, saya sarankan menggunakan array<int,mixed>.

Pada akhirnya, semakin eksplisit, semakin baik.

/** @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 

Kami menggunakan daftar ketika kami memiliki array elemen dengan tipe yang sama.
Untuk melakukannya, kami menggunakan sintaks berlian untuk mendeklarasikan jenis kunci dan nilainya: array<int,mixed>. Ada jalan pintas yang sangat berguna ketika kuncinya adalah bilangan bulat inkremental otomatis: 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);

Kami menggunakan bentuk objek ketika array bukan kumpulan objek tetapi peta yang menyimpan informasi.
Untuk melakukan itu, kami menggunakan sintaks kurung kurawal dan menentukan nama kunci dan jenisnya, kami dapat membaginya dengan koma jika ada beberapa elemen: .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;
}

Tentu saja, dimungkinkan untuk merepresentasikan struktur array kompleks apa pun di PHP dengan komentar PHP ini. Contoh:

/**
 * @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(),
        ],
    ],
    // ...
];

Sumber daya:

  • Mazmur | Bentuk Larik
  • PHPStan | Jenis PHPDoc