Anggota static adalah properti, metode, dan konstanta yang melekat pada kelasnya, bukan pada masing-masing objek yang dibuat darinya. Topik ini membahas cara mendeklarasikan dan mengakses anggota static, konstanta kelas untuk nilai bersama yang tetap, serta late static binding yang mengatur kelas mana yang dimaksud oleh static:: pada saat program berjalan. Contohnya tetap memakai domain perpustakaan, yaitu penomoran kartu anggota, batas peminjaman, dan pelabelan katalog.
Properti dan metode static#
Properti static dideklarasikan dengan kata kunci static setelah kata kunci visibilitasnya. Aksesnya dilakukan melalui nama kelas dengan operator titik dua ganda ::, misalnya Anggota::$jumlah. Hanya ada satu salinan untuk seluruh program, sehingga nilainya dibagi oleh semua objek yang dibuat dari kelas tersebut. Metode static diperlakukan sama, yaitu dipanggil sebagai Kelas::metode() tanpa perlu membuat objek terlebih dahulu.
Metode static tidak dapat menggunakan $this karena tidak ada objek yang sedang menjalankannya. Metode static tetap dapat membaca dan mengubah properti static melalui self::, yaitu penunjuk ke kelas tempat kode itu ditulis. Pola yang cocok untuk anggota static antara lain penghitung bersama, kode berurutan, dan utilitas yang tidak memerlukan keadaan objek.
Skrip berikut memakai satu properti static sebagai penghitung jumlah anggota yang pernah dibuat. Constructor menaikkan penghitung tersebut dan menyusun nomor kartu anggota dari nilai terbarunya, sehingga setiap objek baru memperoleh kode yang berurutan.
<?php
declare(strict_types=1);
class Anggota
{
public string $nama;
public string $kode;
public static int $jumlah = 0;
public function __construct(string $nama)
{
self::$jumlah++;
$this->nama = $nama;
$this->kode = sprintf('AGT-%03d', self::$jumlah);
}
public static function total(): int
{
return self::$jumlah;
}
}
echo Anggota::total(), "\n";
$ali = new Anggota('Ali');
$budi = new Anggota('Budi');
echo $ali->kode, "\n";
echo $budi->kode, "\n";
echo Anggota::total(), "\n";0
AGT-001
AGT-002
2Keluaran memperlihatkan perilaku yang melekat pada kelas. Baris pertama bernilai 0 karena pemanggilan dilakukan sebelum ada objek, dua baris berikutnya membuktikan penghitung itu terus bertambah lintas objek, dan baris terakhir mengembalikan nilai yang sama dari metode static total(). Properti $nama dan $kode tetap milik masing-masing objek, sehingga kelas ini memadukan keadaan per objek dan keadaan bersama dalam satu tempat.
Konstanta kelas#
Konstanta kelas menyimpan nilai yang tetap dan melekat pada kelas, ditulis dengan kata kunci const di dalam tubuh kelas. Aksesnya memakai :: seperti anggota static, dan nilainya wajib berupa ekspresi konstan, misalnya angka, string, array literal, atau ekspresi yang hanya melibatkan nilai konstan. Konstanta kelas dapat diberi visibilitas sejak PHP 7.1, sehingga konstanta yang hanya dipakai internal dapat dibuat private.
Konstanta kelas menggantikan angka dan teks ajaib (magic number dan magic string) yang tersebar di banyak tempat. Ketika nilai berubah, perubahan cukup dilakukan satu kali pada satu tempat, dan seluruh kode yang memakainya otomatis mengikuti. Di dalam metode, konstanta milik kelas sendiri diakses melalui self::NAMA, sedangkan konstanta milik kelas lain ditulis dengan nama kelasnya, misalnya Aturan::BATAS.
Skrip berikut mendefinisikan batas peminjaman sebagai konstanta kelas, memakainya di dalam metode untuk menolak peminjaman yang melebihi batas, lalu menampilkan nilainya dari luar kelas.
<?php
declare(strict_types=1);
class Anggota
{
public const BATAS_PINJAM = 3;
public const STATUS_AKTIF = 'aktif';
private int $jumlahPinjaman = 0;
public function pinjam(): bool
{
if ($this->jumlahPinjaman >= self::BATAS_PINJAM) {
return false;
}
$this->jumlahPinjaman++;
return true;
}
}
echo 'Batas pinjam: ', Anggota::BATAS_PINJAM, "\n";
$anggota = new Anggota();
$anggota->pinjam();
$anggota->pinjam();
$anggota->pinjam();
if ($anggota->pinjam()) {
echo 'pinjam keempat berhasil', "\n";
} else {
echo 'pinjam keempat ditolak, batas ', Anggota::BATAS_PINJAM, ' tercapai', "\n";
}
echo 'Status kelas: ', Anggota::STATUS_AKTIF, "\n";Batas pinjam: 3
pinjam keempat ditolak, batas 3 tercapai
Status kelas: aktifLate static binding#
Kata kunci self:: menunjuk kelas tempat kode itu ditulis, dan penentuannya selesai saat program dimuat. Perilaku ini menjadi masalah ketika kelas turunan mendefinisikan ulang anggota static yang sama, karena pemanggilan metode induk melalui self:: tetap membaca anggota milik induk. PHP menyediakan late static binding melalui static::, yaitu penunjuk yang diselesaikan pada saat pemanggilan berlangsung, sehingga kelas yang benar-benar dipanggil itulah yang dipakai.
Skrip berikut mendefinisikan kelas Katalog dengan dua metode, satu memakai self::$label dan satu lagi memakai static::$label. Kelas KatalogMedia kemudian mewarisi keduanya dengan label yang berbeda. Kedua metode dipanggil dari KatalogMedia, dan keluarannya berbeda satu sama lain.
<?php
declare(strict_types=1);
class Katalog
{
public static string $label = 'Katalog umum';
public static function pakaiSelf(): string
{
return self::$label;
}
public static function pakaiStatic(): string
{
return static::$label;
}
}
class KatalogMedia extends Katalog
{
public static string $label = 'Katalog media';
}
echo KatalogMedia::pakaiSelf(), "\n";
echo KatalogMedia::pakaiStatic(), "\n";Katalog umum
Katalog mediaBaris pertama menampilkan Katalog umum karena self::$label pada tubuh pakaiSelf() terikat ke kelas Katalog, tempat kode itu ditulis. Baris kedua menampilkan Katalog media karena static::$label menunggu sampai pemanggilan terjadi, dan pada saat itu kelas yang dipanggil adalah KatalogMedia. Perilaku yang sama juga berlaku pada static::metode() untuk memanggil metode static yang ditimpa di kelas turunan, serta pada new static untuk membuat objek dari kelas yang benar-benar dipanggil.
Kesalahan umum#
- Memakai
$thisdi dalam metode static. Metode static tidak berjalan atas nama objek mana pun, sehingga$thistidak tersedia di dalamnya dan kode seperti itu gagal sebelum program berjalan. Apabila metode memang perlu membaca keadaan objek, jadikan metode itu metode biasa, bukan metode static. - Mengakses properti static melalui objek. Tulisan
$anggota->jumlahuntuk properti static tidak membaca anggota static yang dimaksud dan memicu peringatan properti tidak terdefinisi. GunakanAnggota::$jumlah, dan panggil metode static melalui nama kelasnya agar maksudnya terbaca. - Mengira
self::mengikuti kelas yang dipanggil. Metode induk yang memakaiself::selalu merujuk ke kelas induknya meskipun dipanggil dari kelas turunan, sehingga pembaruan anggota static di turunan tidak terlihat. Pilihstatic::apabila perilakunya harus mengikuti kelas pemanggil. - Menyimpan data khusus permintaan di properti static. Dalam aplikasi web, properti static bertahan selama proses berjalan dan dibagi oleh seluruh permintaan yang terjadi di proses itu. Akibatnya, data satu pengguna dapat bocor ke pengguna lain apabila penempatannya keliru. Data yang melekat pada satu permintaan atau satu pengguna ditempatkan pada objek atau penyimpanan yang dirancang untuk itu.
Ringkasan#
- Anggota static melekat pada kelas, diakses melalui
Kelas::anggota, dan hanya mempunyai satu salinan untuk seluruh program, sedangkan$thistidak tersedia di dalam metode static. - Konstanta kelas menyimpan nilai tetap bersama dengan visibilitas yang dapat diatur, dan menggantikan angka atau teks ajaib yang tersebar di banyak tempat.
self::terikat ke kelas tempat kode ditulis, sedangkanstatic::dengan late static binding terikat ke kelas yang benar-benar dipanggil, sehingga keduanya dapat menghasilkan keluaran yang berbeda pada pewarisan.- Properti static adalah keadaan bersama, sehingga pemakaiannya harus disengaja dan tidak boleh menggantikan keadaan yang seharusnya milik objek.
Referensi#
- Static Keyword — Manual PHP — Menetapkan deklarasi dan akses properti serta metode static.
- Late Static Bindings — Manual PHP
— Menjelaskan perbedaan
self::danstatic::beserta contohnya. - Class Constants — Manual PHP
— Mendokumentasikan
constpada kelas, visibilitasnya, dan aturan nilainya.