Static, Konstanta Class & Magic Methods
Anggota static, konstanta class, late static binding, serta magic method (__toString, __get, __set, __call, __invoke) untuk membuat class yang ringkas dan ekspresif.
Static: milik class, bukan milik objek
Properti dan method biasa dimiliki tiap objek (setiap objek punya nilainya sendiri). Anggota static dimiliki class itu sendiri dan dipakai bersama. Aksesnya memakai ::, tanpa perlu membuat objek.
class Penghitung
{
private static int $total = 0;
public static function tambah(): int
{
return ++self::$total; // self:: = class ini
}
}
Penghitung::tambah(); // 1
Penghitung::tambah(); // 2
- Di dalam method static tidak ada
$this(tidak ada objek). Pakaiself::ataustatic::. - Cocok untuk fungsi utilitas dan factory. Hindari menyimpan keadaan yang berubah di static: sulit diuji dan berbahaya di aplikasi besar.
Konstanta class
class Lingkaran
{
public const PI = 3.14159;
final public const SISI_MIN = 0; // final: tidak bisa ditimpa subclass (PHP 8.1)
public static function luas(float $r): float
{
return self::PI * $r ** 2;
}
}
echo Lingkaran::PI;
echo Lingkaran::luas(2);
Konstanta ditulis dengan HURUF_BESAR dan diakses lewat NamaClass::NAMA. Untuk sekumpulan nilai tetap, enum (bab sebelumnya) biasanya pilihan yang lebih baik.
Named constructor (factory method)
class Pengguna
{
private function __construct(public readonly string $nama, public readonly string $peran) {}
public static function admin(string $nama): self
{
return new self($nama, 'admin');
}
public static function tamu(): self
{
return new self('Tamu', 'tamu');
}
}
$a = Pengguna::admin('Budi');
Constructor private memaksa pembuatan objek lewat method yang namanya jelas. Pola ini sangat umum.
self vs static (late static binding)
class Hewan
{
public static function buat(): static
{
return new static(); // membuat class yang MEMANGGIL, bukan class tempat kode ditulis
}
}
class Kucing extends Hewan {}
get_class(Kucing::buat()); // "Kucing". Jika memakai new self() hasilnya "Hewan"
Magic methods
Method berawalan __ yang dipanggil PHP otomatis pada situasi tertentu.
| Method | Dipanggil saat |
|---|---|
__construct | Objek dibuat |
__toString | Objek dipakai sebagai string (echo $obj) |
__get($nama) | Membaca properti yang tidak bisa diakses/tidak ada |
__set($nama, $nilai) | Menulis properti yang tidak bisa diakses/tidak ada |
__isset / __unset | isset() / unset() pada properti tidak ada |
__call($nama, $args) | Memanggil method yang tidak ada |
__callStatic | Memanggil method static yang tidak ada |
__invoke | Objek dipanggil seperti fungsi: $obj() |
__clone | Setelah objek disalin dengan clone |
__toString
class Uang
{
public function __construct(private int $jumlah) {}
public function __toString(): string
{
return 'Rp ' . number_format($this->jumlah, 0, ',', '.');
}
}
echo new Uang(1500000); // Rp 1.500.000
__get dan __set: properti dinamis
class Konfigurasi
{
private array $data = [];
public function __get(string $nama): mixed
{
return $this->data[$nama] ?? null;
}
public function __set(string $nama, mixed $nilai): void
{
$this->data[$nama] = $nilai;
}
}
$k = new Konfigurasi();
$k->tema = 'gelap'; // memanggil __set
echo $k->tema; // memanggil __get
__call: meneruskan method
class Pembungkus
{
public function __construct(private object $target) {}
public function __call(string $method, array $args): mixed
{
echo "Memanggil $method\n";
return $this->target->$method(...$args);
}
}
__invoke: objek yang bisa dipanggil
class Pengali
{
public function __construct(private int $faktor) {}
public function __invoke(int $x): int
{
return $x * $this->faktor;
}
}
$kali3 = new Pengali(3);
echo $kali3(5); // 15
print_r(array_map($kali3, [1, 2, 3])); // [3, 6, 9]
Pakai secukupnya
Magic method kuat tetapi membuat kode lebih sulit dilacak dan tidak dikenali IDE. Properti yang jelas dan method yang jelas hampir selalu lebih baik. Cukup andalkan __toString, __invoke, dan __construct sebagai kebiasaan; __get/__set/__call untuk kasus khusus.
Error umum
Using $this when not in object context→ memakai$thisdi method static.Cannot instantiate class(constructor private) → gunakan named constructor.Object of class X could not be converted to string→ belum membuat__toString.