PHP menyediakan berbagai fungsi untuk melakukan introspeksi object, yaitu mengetahui informasi tentang class, method, property, serta hubungan antara class dan subclass. Dengan introspeksi ini, kita bisa melihat struktur pewarisan, daftar method yang bisa dipanggil, serta property yang dimiliki suatu object.
Untuk mengetahui method yang dapat dipanggil dalam suatu object (termasuk method yang diwarisi dari parent class), kita bisa menggunakan ReflectionClass.
ReflectionClass
function getCallableMethods($object): array { $refleksi = new ReflectionClass($object); return $refleksi->getMethods(); }
ReflectionClass($object) membuat representasi class dari object yang diberikan. getMethods() mengembalikan daftar method yang tersedia dalam bentuk array.
Untuk mengetahui parent class dari suatu object, kita bisa menggunakan getParentClass() secara rekursif.
function getLineage($object): array { $refleksi = new ReflectionClass($object); if ($refleksi->getParentClass()) { $parent = $refleksi->getParentClass(); $lineage = getLineage($parent); $lineage[] = $refleksi->getName(); } else { $lineage = [$refleksi->getName()]; } return $lineage; }
Jika class memiliki parent, kita akan terus mencari hingga ke tingkat tertinggi. Menggunakan array rekursif untuk menyusun urutan pewarisan.
Jika kita ingin mengetahui class mana saja yang mewarisi class tertentu, kita bisa menggunakan get_declared_classes() untuk mendapatkan semua class yang ada, lalu mengecek apakah masing-masing merupakan subclass dari class yang kita analisis.
function getChildClasses($object): array { $refleksi = new ReflectionClass($object); $classes = get_declared_classes(); $children = []; foreach ($classes as $class) { $checkedReflection = new ReflectionClass($class); if ($checkedReflection->isSubclassOf($refleksi->getName())) { $children[] = $checkedReflection->getName(); } } return $children; }
function getProperties($object): array { $refleksi = new ReflectionClass($object); return $refleksi->getProperties(); }
get_declared_classes() mengambil semua class yang ada dalam skrip. isSubclassOf() digunakan untuk mengecek apakah suatu class merupakan subclass dari class yang dianalisis.
Untuk mengetahui property dalam suatu object, kita bisa menggunakan getProperties() dari ReflectionClass.
function printObjectInfo($object) { $refleksi = new ReflectionClass($object); echo "Class"; echo "{$refleksi->getName()}"; echo "Inheritance"; echo "Parent Classes"; $lineage = getLineage($object); array_pop($lineage); echo count($lineage) > 0 ? "" . implode(" -> ", $lineage) . "" : "None"; echo "Child Classes"; $children = getChildClasses($object); echo "" . (count($children) > 0 ? implode(", ", $children) : "None") . ""; echo "Methods"; $methods = getCallableMethods($object); echo count($methods) > 0 ? implode("", array_map(fn($m) => "{$m->getName()}()", $methods)) : "None"; echo "Properties"; $properties = getProperties($object); if (count($properties) > 0) { foreach ($properties as $property) { $name = $property->getName(); $value = property_exists($object, $name) ? $object->$name : "Tidak diatur"; echo "\${$name} = {$value}"; } } else { echo "None"; } echo ""; }
{$refleksi->getName()}
" . implode(" -> ", $lineage) . "
" . (count($children) > 0 ? implode(", ", $children) : "None") . "
Sekarang, mari kita buat contoh class yang akan dianalisis menggunakan fungsi di atas.
class Kendaraan { public $merk = "Toyota"; public $tahun = 2020; public function info() { return "Kendaraan ini adalah {$this->merk} keluaran tahun {$this->tahun}."; } } class Mobil extends Kendaraan { public $jumlahPintu = 4; public function suaraKlakson() { return "Beep beep!"; } } class Truk extends Kendaraan { public $kapasitasMuat = 10000; public function infoTruk() { return "Truk ini memiliki kapasitas muat {$this->kapasitasMuat} kg."; } } $kendaraan = new Kendaraan(); $mobil = new Mobil(); $truk = new Truk(); printObjectInfo($kendaraan); printObjectInfo($mobil); printObjectInfo($truk);
Output yang dihasilkan:
Class Kendaraan Inheritance Parent Classes None Child Classes Mobil, Truk Methods info() Properties $merk = Toyota $tahun = 2020 ------------------- Class Mobil Inheritance Parent Classes Kendaraan Child Classes None Methods info() suaraKlakson() Properties $merk = Toyota $tahun = 2020 $jumlahPintu = 4 ------------------- Class Truk Inheritance Parent Classes Kendaraan Child Classes None Methods info() infoTruk() Properties $merk = Toyota $tahun = 2020 $kapasitasMuat = 10000
Ayo buktikan pemahamanmu!
Lengkapilah kode program berikut agar dapat mencetak daftar method yang dapat dipanggil dari class Printer, termasuk yang diwarisi dari class induknya. Gunakan ReflectionClass untuk mendapatkan informasi tersebut dan pastikan konstruktor class induk dipanggil secara tepat.
Printer
<?php class Perangkat { public $nama; public function __construct($nama) { $this->nama = $nama; } public function hidupkan() { return "{$this->nama} dihidupkan."; } } class Printer extends Perangkat { public $warna; public function __construct($nama, $warna) { ::__construct($nama); $this->warna = $warna; } public function cetak() { return "Mencetak dokumen berwarna {$this->warna}."; } } $printer = new Printer("Canon Pixma", "merah"); $refleksi = new ($printer); $methodList = $refleksi->(); foreach ($methodList as $method) { echo $method->getName() . "<br>"; } ?>