Pendahuluan — pintu terakhir sebelum Laravel
Di Property, Method & Constructor (#54) kamu sudah bisa membuat object Buku yang lahir lengkap. Artikel ini adalah #55 (ini) — langkah ketiga (dan terakhir) jembatan OOP PHP sebelum Laravel.
Dua ide saja yang kita rapikan: visibility (siapa boleh menyentuh data) dan composition (object memakai object lain). Analoginya: laci buku boleh dikunci (private), dan perpustakaan memakai banyak buku — bukan “jadi buku”.
Prasyarat: sudah baca Property, Method & Constructor (#54) — paham
class, property, method, dan__construct. Domain tetap perpustakaan mini.
Visibility — siapa boleh menyentuh?
| Kata kunci | Arti awam | Kapan dipakai di artikel ini |
|---|---|---|
public |
Boleh disentuh dari luar class | Method yang memang untuk dipanggil pemakai |
private |
Hanya class sendiri yang boleh | Property penting agar tidak diacak sembarangan |
protected |
Untuk class anak (inheritance) | Disebut saja — belum kita dalami di sini |
Jangan hafal semua dulu. Fokus: public vs private. Itu sudah cukup untuk jembatan ke Laravel.
Masalah kalau semua public
Property public nyaman, tapi mudah “dirusak” dari luar:
<?php
class Buku
{
public string $judul;
public int $tahun;
public function __construct(string $judul, int $tahun)
{
$this->judul = $judul;
$this->tahun = $tahun;
}
}
$buku = new Buku("Belajar PHP", 2024);
$buku->tahun = -99; // oops — tahun mustahil, tapi PHP diam saja
echo $buku->tahun, PHP_EOL;
Output:
-99
Object tetap “hidup”, tapi datanya sudah tidak masuk akal. Di aplikasi web, bug seperti ini sering datang dari form/API yang mengisi field sembarangan.
Private + method — laci terkunci
Kunci property dengan private, lalu sediakan method yang mengontrol perubahan:
<?php
class Buku
{
private string $judul;
private int $tahun;
public function __construct(string $judul, int $tahun)
{
$this->judul = $judul;
$this->setTahun($tahun);
}
public function info(): string
{
return "{$this->judul} ({$this->tahun})";
}
public function setTahun(int $tahun): void
{
if ($tahun < 1900 || $tahun > 2100) {
throw new InvalidArgumentException("Tahun tidak masuk akal: {$tahun}");
}
$this->tahun = $tahun;
}
}
$buku = new Buku("Belajar PHP", 2024);
echo $buku->info(), PHP_EOL;
Output:
Belajar PHP (2024)
Dari luar class, $buku->tahun = -99 akan ditolak PHP (Cannot access private property). Perubahan tahun harus lewat setTahun() — satu pintu, satu aturan.
Kalau kamu kirim tahun mustahil lewat pintu itu — misalnya $buku->setTahun(1800) — PHP akan melempar InvalidArgumentException (pesan error yang kita tulis sendiri). Itu sengaja: lebih baik gagal keras daripada menyimpan data bohong.
Awam: private bukan “rahasia negara”. Ia artinya: “kalau mau ubah, lewat pintu yang sudah kita sediakan.”
public. Data penting tetap di laci private.Composition — object memakai object
Composition artinya: sebuah object memiliki / memakai object lain. Bukan “mewarisi” (inheritance) — itu topik lain dan sering keburu rumit untuk awam.
Contoh: Katalog menyimpan banyak Buku. Katalog bukan buku; ia mengumpulkan buku.
<?php
class Buku
{
private string $judul;
public function __construct(string $judul)
{
$this->judul = $judul;
}
public function judul(): string
{
return $this->judul;
}
}
class Katalog
{
/** @var list<Buku> daftar Buku di dalam katalog */
private array $koleksi = [];
public function tambah(Buku $buku): void
{
$this->koleksi[] = $buku;
}
public function jumlah(): int
{
return count($this->koleksi);
}
public function daftar(): string
{
$baris = [];
foreach ($this->koleksi as $buku) {
$baris[] = "- ".$buku->judul();
}
return implode(PHP_EOL, $baris);
}
}
$katalog = new Katalog();
$katalog->tambah(new Buku("Belajar PHP"));
$katalog->tambah(new Buku("Laravel Praktis"));
echo "jumlah=", $katalog->jumlah(), PHP_EOL;
echo $katalog->daftar(), PHP_EOL;
Output:
jumlah=2
- Belajar PHP
- Laravel Praktis
Ini pola yang nanti sering muncul di Laravel: controller tipis (pintu HTTP — terima request, kirim jawaban) dan service / class domain (tempat aturan bisnis). Ide-nya sama: potong tanggung jawab, jangan satukan semua di satu file panjang.
Awam: baris @var list<Buku> di komentar hanya catatan untuk manusia/IDE — “koleksi ini isinya object Buku”. PHP tidak wajib membacanya agar program jalan.
Pola Dasar — visibility & composition
-
1
Kunci data penting Property kritis =
private(tahun, stok, harga, status). -
2
Buka pintu lewat method
info(),setTahun(),judul()— aturan hidup di sini. -
3
Pisahkan “benda” dan “pengelola”
BukuvsKatalog— jangan saturasi satu class raksasa. -
4
Composition dulu, inheritance belakangan “Memakai” object lain biasanya lebih mudah dipahami awam.
-
5
Baru bawa ke Laravel Berikutnya: Laravel routing & JSON (#56) — pintu HTTP nyata di framework.
Kode lengkap — oop_php_visibility.php
Simpan dan jalankan: php oop_php_visibility.php. Perhatikan: property private, perubahan lewat method, dan Katalog yang memakai Buku.
<?php
/**
* Visibility & composition ringan (Seri 4 #55).
* Lanjut: Laravel routing & JSON di artikel berikutnya.
*/
declare(strict_types=1);
class Buku
{
private string $judul;
private string $penulis;
private int $tahun;
public function __construct(string $judul, string $penulis, int $tahun)
{
$this->judul = $judul;
$this->penulis = $penulis;
$this->setTahun($tahun);
}
public function info(): string
{
return "{$this->judul} oleh {$this->penulis} ({$this->tahun})";
}
public function setTahun(int $tahun): void
{
if ($tahun < 1900 || $tahun > 2100) {
throw new InvalidArgumentException("Tahun tidak masuk akal: {$tahun}");
}
$this->tahun = $tahun;
}
}
class Katalog
{
/** @var list<Buku> daftar Buku di dalam katalog */
private array $koleksi = [];
public function tambah(Buku $buku): void
{
$this->koleksi[] = $buku;
}
public function jumlah(): int
{
return count($this->koleksi);
}
public function daftar(): string
{
$baris = [];
foreach ($this->koleksi as $buku) {
$baris[] = $buku->info();
}
return implode(PHP_EOL, $baris);
}
}
function demo(): void
{
$katalog = new Katalog();
$katalog->tambah(new Buku("Belajar PHP", "Sari", 2024));
$katalog->tambah(new Buku("Laravel Praktis", "Budi", 2025));
echo $katalog->daftar(), PHP_EOL;
echo "jumlah=", $katalog->jumlah(), PHP_EOL;
}
demo();
Output yang diharapkan:
Belajar PHP oleh Sari (2024)
Laravel Praktis oleh Budi (2025)
jumlah=2
Kesalahan umum
| Gejala | Penyebab tipikal | Perbaikan |
|---|---|---|
Cannot access private property |
Mengisi property private dari luar | Pakai method public (getter/setter/aturan) |
| Data tetap “liar” | Property masih public |
Kunci dengan private + validasi di method |
| Class raksasa | Semua logika digabung ke Buku |
Pisah pengelola: Katalog / service tipis |
| Langsung warisan rumit | Loncat ke inheritance | Composition dulu — “memakai”, bukan “menjadi” |
| Langsung buka Laravel | Fondasi object belum rapat | Selesaikan jembatan OOP PHP dulu (Mengenal OOP PHP (#53) sampai #55 (ini)) |
Latihan singkat
- Tambah method
judul(): stringdiBuku(kode lengkap) yang mengembalikan judul private. - Di
setTahun(), coba kirim tahun1800dan pastikan exception muncul (hapus dulu dari demo jika perlu). - Tambah buku ketiga ke
Katalogdan pastikanjumlah=menjadi 3.
FAQ singkat
Harus selalu private?
Untuk data yang punya aturan (tahun, stok, status): ya, lebih aman. Method yang memang untuk dipanggil pemakai: biarkan public.
Apa bedanya composition dan inheritance?
Composition = “memakai” (katalog punya buku). Inheritance = “menjadi jenis khusus dari”. Di Seri 4 kita prioritaskan composition karena lebih mudah dibawa ke service Laravel.
Apakah ini sudah cukup untuk Laravel?
Untuk fondasi object: ya. Berikutnya kita pakai framework untuk route HTTP & JSON — ide object-nya tetap sama.
Lanjut ke mana?
Berikutnya: Laravel Routing & JSON (#56) — pintu HTTP nyata, artikel pertama stack Laravel di Seri 4.
Kesimpulan & langkah berikutnya
private melindungi data. Method public menjadi pintu. Composition membagi kerja antar object. Tiga kebiasaan ini yang membuat controller Laravel tidak jadi tempat sampah.
Artikel ini adalah #55 (ini) — penutup jembatan OOP PHP setelah Property, Method & Constructor (#54) dan Mengenal OOP PHP (#53).
Seri 4 progress: langkah #55 (ini) · 4/8 menuju Capstone Laravel · jembatan OOP PHP 3/3 selesai · prasyarat: Property, Method & Constructor (#54) LIVE. Berikutnya: Laravel Routing & JSON (#56).