PHP Oop Namespace Autoloading Traits Visibility
Definisi
Object-Oriented Programming (OOP) di PHP adalah pendekatan menyusun kode dengan memodelkan data dan perilaku sebagai class dan object. Alih-alih menaruh semua logika di dalam fungsi-fungsi lepas, OOP mengelompokkan state dan behavior ke dalam unit yang lebih jelas tanggung jawabnya.
Topik yang paling sering muncul di PHP OOP adalah:
- class: cetak biru untuk membuat object
- object: instance nyata dari class
- namespace: pengelompokan nama agar class/function/const tidak saling tabrakan
- autoloading: mekanisme memuat class secara otomatis saat dibutuhkan
- traits: cara berbagi implementasi antarclass tanpa inheritance penuh
- visibility: aturan akses
public,protected, danprivate
Kalau dasar ini rapi, struktur project PHP jadi lebih mudah dirawat dan lebih aman dari tabrakan nama.
Procedural vs OOP
Pendekatan procedural
Pada pendekatan procedural, program dibangun dari rangkaian fungsi yang memproses data secara bertahap.
Contoh bentuk sederhananya:
<?php
function calculateTotal(array $items): float
{
$total = 0;
foreach ($items as $item) {
$total += $item['price'] * $item['qty'];
}
return $total;
}Ciri utamanya:
- fokus ke alur langkah demi langkah
- data sering dipassing dari satu fungsi ke fungsi lain
- cocok untuk skrip kecil, utilitas, atau tugas yang sifatnya linear
- struktur biasanya lebih cepat ditulis di awal
Pendekatan OOP
Pada pendekatan OOP, data dan perilaku dikumpulkan dalam class.
<?php
class Cart
{
public function __construct(private array $items = []) {}
public function total(): float
{
$total = 0;
foreach ($this->items as $item) {
$total += $item['price'] * $item['qty'];
}
return $total;
}
}Ciri utamanya:
- fokus ke objek yang punya state dan behavior
- logika dikelompokkan berdasarkan tanggung jawab
- lebih enak dipakai saat domain aplikasi makin besar
- lebih mudah dibagi menjadi layer atau service yang jelas
Kapan memilih yang mana
Pilih procedural kalau:
- skripnya kecil dan jelas
- logic-nya linear
- belum ada kebutuhan reuse yang kuat
- overhead struktur OOP justru bikin berisik
Pilih OOP kalau:
- aplikasi punya banyak entitas dan tanggung jawab
- ada kebutuhan pemisahan concern yang rapi
- logika perlu diuji dan di-extend lebih sering
- project akan tumbuh dan dikerjakan beberapa orang
Kesalahan umum adalah memaksakan OOP untuk semua hal. Kalau satu fungsi kecil sudah cukup, tidak perlu dibuat jadi tiga class hanya demi terlihat “rapi”.
Class dan object
Class
Class adalah template. Di dalam class biasanya ada properties dan methods.
<?php
class User
{
public function __construct(
public string $name,
private string $email,
) {}
public function displayName(): string
{
return $this->name;
}
}Class menjelaskan:
- data apa yang dimiliki object
- perilaku apa yang bisa dilakukan object
- batas akses untuk setiap bagian
Object
Object adalah instance dari class.
<?php
$user = new User('Hadie', 'hadie@example.com');
echo $user->displayName();Satu class bisa dipakai untuk membuat banyak object dengan nilai state yang berbeda.
Inti relasinya
- class = cetakan
- object = hasil cetakan
- method = perilaku
- property = data/state
Contoh alur sederhana
Namespace
Namespace dipakai untuk mengelompokkan identifier dan mencegah tabrakan nama. Ini penting karena di PHP, class bernama sama bisa muncul di library berbeda.
<?php
namespace App\Service;
class PaymentService
{
}Pemakaian dari luar namespace:
<?php
use App\Service\PaymentService;
$service = new PaymentService();Kapan namespace penting
Namespace penting ketika:
- project mulai punya banyak class
- ada vendor package dari Composer
- ada kemungkinan nama class yang sama di domain berbeda
- project memakai struktur folder modern seperti
App\Service,App\Controller,App\Domain
Kalau project masih kecil, namespace sering terasa opsional. Tapi begitu jumlah class naik, namespace jadi penyelamat dari konflik nama dan import yang tidak jelas.
Struktur namespace yang sehat
Pola yang umum:
App\ControllerApp\ServiceApp\RepositoryApp\DomainApp\Support
Jangan membuat namespace terlalu dalam tanpa alasan. Terlalu banyak level bisa membuat class sulit ditemukan dan hubungan antarbagian jadi kabur.
Diagram struktur namespace
Autoloading
Autoloading adalah mekanisme untuk memuat class secara otomatis saat class itu dipakai, tanpa perlu require manual di setiap file.
Contoh klasik sebelum autoloading:
<?php
require 'src/User.php';
require 'src/Order.php';
require 'src/Payment.php';Dengan autoloading, PHP akan memanggil loader saat class belum ditemukan.
Kenapa autoloading penting
Autoloading penting ketika:
- jumlah file mulai banyak
- project memakai Composer
- class tersebar di banyak folder
- kamu ingin entry point tetap bersih
- test, CLI command, dan web request memakai struktur class yang sama
Tanpa autoloading, file include manual cepat jadi rapuh:
- urutan
requirebisa salah - file bisa dobel include
- maintainability turun
- refactor namespace jadi mahal
Composer autoload
Di project modern, autoloading biasanya diatur lewat composer.json.
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}Dengan mapping ini:
App\Service\PaymentService→src/Service/PaymentService.phpApp\Controller\UserController→src/Controller/UserController.php
Setelah mengubah autoload, jalankan:
composer dump-autoloadKapan autoloading jadi wajib secara praktis
Secara teknis kamu masih bisa tanpa autoloading, tetapi secara praktik autoloading hampir wajib saat:
- memakai Composer dependency
- struktur folder mengikuti PSR-4
- project dikerjakan lebih dari satu orang
- ada banyak class yang dipakai lintas layer
Alur kerja autoloading
Traits
Traits dipakai untuk berbagi implementasi method antarclass tanpa harus memakai inheritance penuh.
<?php
trait HasUuid
{
public function generateUuid(): string
{
return bin2hex(random_bytes(16));
}
}
class Order
{
use HasUuid;
}Kapan traits cocok
Traits cocok untuk hal yang:
- reusable
- berbentuk implementasi kecil
- tidak layak jadi parent class
- dibutuhkan oleh banyak class yang tidak punya hubungan warisan yang sama
Contoh umum:
- helper format data
- logging kecil
- timestamp/uuid generation
- shared behavior pada beberapa service
Kapan traits perlu dihindari
Traits bisa jadi jebakan kalau dipakai untuk menutupi desain yang sebenarnya butuh komposisi atau interface.
Hindari traits kalau:
- trait terlalu besar
- trait menyimpan banyak state
- method trait bergantung pada property tersembunyi
- kamu memakai traits sebagai “tempat buang” kode bersama
Kalau trait mulai terasa seperti class mini, biasanya desainnya sudah salah arah.
Visibility
Visibility menentukan siapa yang boleh mengakses property atau method.
public
Bisa diakses dari mana saja.
class User
{
public string $name;
}Dipakai untuk API yang memang dirancang terbuka.
protected
Bisa diakses dari class itu sendiri dan subclass.
class BaseLogger
{
protected function write(string $message): void
{
// ...
}
}Cocok untuk detail internal yang masih perlu dipakai turunan.
private
Hanya bisa diakses dari class itu sendiri.
class TokenService
{
private function hash(string $value): string
{
return password_hash($value, PASSWORD_DEFAULT);
}
}Cocok untuk helper internal dan detail implementasi yang tidak perlu diekspos.
Praktik yang sehat
Aturan praktisnya:
- mulai dari visibility paling ketat yang masuk akal
- buka akses hanya kalau benar-benar dibutuhkan
- jangan jadikan semua property
publichanya demi cepat - pakai method untuk menjaga aturan validasi dan invariant object
Visibility yang rapi membantu object tetap konsisten.
Pola project PHP yang umum
Struktur project biasanya makin sehat kalau namespace, folder, dan autoloading dibuat selaras.
Contoh sederhana:
src/
Controller/
Service/
Repository/
Domain/
Support/Contoh pemetaan:
- folder
src/Service→ namespaceApp\Service - folder
src/Controller→ namespaceApp\Controller - folder
src/Domain→ namespaceApp\Domain
Kalau struktur ini konsisten, developer bisa menebak lokasi class hanya dari namanya.
Jebakan umum saat menyusun struktur project PHP
1. Campur procedural dan OOP tanpa batas yang jelas
Ini sering terjadi saat file lama tetap dipakai, lalu class baru ditambahkan tanpa strategi.
Akibatnya:
- alur program sulit diikuti
- dependency jadi acak
- tanggung jawab file tidak jelas
2. Namespace tidak konsisten dengan folder
Kalau namespace tidak mengikuti struktur file, autoloading jadi membingungkan.
Contoh masalah:
- class ada di folder
Service, tapi namespace-nyaApp\Utils - file berpindah, tapi mapping autoload tidak diperbarui
3. Terlalu banyak require manual
Ini tanda project belum memanfaatkan autoloading dengan benar.
Risikonya:
- urutan include rawan error
- file dobel include
- refactor jadi mahal
4. Trait dipakai untuk menyembunyikan desain yang belum matang
Kalau implementasi bersama sebenarnya berbeda secara konsep, trait bukan jawaban otomatis.
5. Visibility terlalu longgar
Kalau semuanya public, object kehilangan kontrol atas state-nya.
6. Class terlalu besar dan menampung semua hal
Gejalanya:
- satu class punya terlalu banyak method
- tanggung jawab campur aduk
- sulit diuji dan sulit dipecah
7. Namespace terlalu dalam
Struktur yang terlalu bertingkat sering bikin nama class panjang, sulit dibaca, dan terlalu birokratis.
Contoh struktur yang masuk akal
src/
Domain/
User.php
Repository/
UserRepository.php
Service/
UserService.php
Controller/
UserController.phpAlurnya biasanya begini:
- Controller menerima request.
- Controller memanggil Service.
- Service menjalankan aturan bisnis.
- Repository mengurus data.
- Domain object membawa state utama.
Pola ini bukan satu-satunya jawaban, tetapi cukup stabil untuk banyak project PHP modern.
Catatan implementasi
- Gunakan OOP kalau tanggung jawab aplikasi mulai bertambah.
- Gunakan procedural untuk skrip kecil atau tugas linear.
- Selaraskan nama folder, namespace, dan autoloading sejak awal.
- Pakai Composer autoload agar
requiremanual tidak membesar. - Gunakan traits hanya untuk reuse yang kecil dan jelas.
- Jaga visibility seketat mungkin.
- Hindari class gemuk yang menampung terlalu banyak concern.
- Jangan over-engineer struktur di project yang masih sangat kecil.
Istilah
- Class: cetakan untuk membuat object.
- Object: instance nyata dari class.
- Namespace: ruang nama untuk mencegah tabrakan identifier.
- Autoloading: pemuatan class otomatis saat class dipakai.
- Trait: mekanisme reuse method tanpa inheritance penuh.
- Visibility: aturan akses terhadap property dan method.
- PSR-4: standar pemetaan namespace ke struktur folder/file.
- Inheritance: pewarisan perilaku dari parent class ke child class.
- Composition: membangun object dari object lain.