Horizontal Code Reuse & Struktur Kode yang Rapi
usePHP hanya mendukung Single Inheritance. Sebuah class hanya bisa extends satu parent class.
Bagaimana jika kita ingin menggunakan method yang sama di beberapa class yang tidak saling berhubungan?
class A {
public function log() { ... }
}
class B extends A { ... }
// Class C butuh method log() juga,
// tapi sudah extends class lain.
class C extends OtherClass {
// Error: Cannot extend A too
}
Traits adalah mekanisme untuk code reuse (penggunaan kembali kode) pada bahasa yang mendukung single inheritance seperti PHP.
Traits memungkinkan developer untuk me-reuse method-method dalam beberapa class yang independen.
Gunakan keyword trait diikuti dengan nama trait.
trait Logger {
public function log($message) {
echo date('Y-m-d H:i:s') . ": " . $message;
}
}
Gunakan keyword use di dalam class untuk memasukkan trait.
class User {
use Logger;
public function create() {
$this->log("User created");
}
}
$user = new User();
$user->create(); // Output: 2023-10-27 10:00:00: User created
Berbeda dengan Inheritance (Vertikal), Traits bekerja secara Horizontal. Class User dan Product tidak perlu memiliki hubungan parent-child.
Sebuah class bisa menggunakan lebih dari satu trait.
trait Hello {
public function sayHello() { echo "Hello"; }
}
trait World {
public function sayWorld() { echo "World"; }
}
class MyWorld {
use Hello, World;
}
Trait juga bisa menggunakan trait lain.
trait HelloWorld {
use Hello, World;
}
class MyClass {
use HelloWorld;
}
Urutan prioritas method jika ada nama yang sama:
class Base {
public function say() { echo "Base"; }
}
trait SayTrait {
public function say() { echo "Trait"; }
}
class Child extends Base {
use SayTrait;
}
$obj = new Child();
$obj->say(); // Output: Trait
Jika dua trait memiliki method dengan nama yang sama, akan terjadi Fatal Error.
trait A { function smallTalk() { echo 'a'; } }
trait B { function smallTalk() { echo 'b'; } }
class Talker {
use A, B; // Fatal Error: Collision
}
Gunakan operator insteadof untuk memilih salah satu.
class Talker {
use A, B {
A::smallTalk insteadof B;
}
}
Gunakan operator as untuk memberi alias pada method yang konflik.
class Talker {
use A, B {
B::smallTalk as talkB;
}
}
Mengorganisir Kode Anda
Namespace adalah cara untuk mengelompokkan class, interface, function, dan constant yang saling berhubungan.
Analogi: Seperti folder di sistem operasi. File home.txt di folder A berbeda dengan
home.txt di folder B.
Nama class harus unik secara global. Ini sulit jika menggunakan library pihak ketiga.
// Library A
class User { ... }
// Library B
class User { ... }
// Error: Cannot redeclare class User
Deklarasikan namespace di baris paling atas file PHP.
namespace App\Models;
class User {
public function __construct() {
echo "User dari App\\Models";
}
}
Standar PSR-4 merekomendasikan struktur folder mengikuti namespace.
Untuk menggunakan class dari namespace lain, kita bisa menggunakan Fully Qualified Name.
$user = new \App\Models\User();
Atau menggunakan keyword use.
Keyword use digunakan untuk mengimpor class/namespace agar tidak perlu menulis nama
lengkapnya berulang kali.
namespace App\Controllers;
use App\Models\User;
class UserController {
public function index() {
$user = new User(); // Tidak perlu \App\Models\User
}
}
Jika ada nama class yang sama dari namespace berbeda, gunakan as.
use App\Models\User;
use App\ThirdParty\User as ThirdPartyUser;
$myUser = new User();
$otherUser = new ThirdPartyUser();
Sejak PHP 7, kita bisa mengelompokkan use statement dari namespace yang sama.
// Sebelum
use App\Models\User;
use App\Models\Product;
// Sesudah
use App\Models\{User, Product};
Class bawaan PHP (seperti Exception, DateTime) berada di global namespace.
Jika kita berada dalam sebuah namespace, akses class global dengan backslash \ di depannya.
namespace App;
function test() {
throw new \Exception("Error!");
}
Ada Pertanyaan?