3. CONTOH PROGRAM INTROSPECTION

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.

Mendapatkan Daftar Method yang Dapat Dipanggil

Untuk mengetahui method yang dapat dipanggil dalam suatu object (termasuk method yang diwarisi dari parent class), kita bisa menggunakan 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.

Mengetahui Pohon Pewarisan (Inheritance Tree)

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.

Mengetahui Subclass dari Suatu Class

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;
}
Mendapatkan Property yang Dimiliki Object
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.

Menampilkan Informasi Lengkap Tentang Object

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 "
"; }
Contoh Class dan Object

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

LATIHAN

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.

<?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>";
}
?>