Web Development

Fitur PHP 8.x yang Wajib Kamu Tahu 2026

Dulu waktu pertama kali pindah dari PHP 7.x ke PHP 8, saya agak skeptis. Kode lama masih jalan, kenapa harus repot upgrade? Ternyata begitu coba fitur-fitur barunya, rasanya kayak naik dari motor ke mobil semuanya lebih smooth dan efisien. Sekarang kalau nemu kode pakai cara lama yang bisa disederhanakan pakai fitur PHP 8.x, langsung kepengen refactor.

PHP 8.0, 8.1, 8.2, dan 8.3 masing-masing bawa perubahan signifikan yang bikin kode lebih aman, lebih cepat, dan lebih enak dibaca. Di sini saya bakal bahas fitur-fitur yang paling sering saya pakai di project sehari-hari, lengkap dengan contoh nyata.

Named Arguments Akhir dari Parameter Bingung

Salah satu masalah klasik di PHP lama: function dengan banyak parameter opsional. Mau skip beberapa parameter di tengah? Harus tetap nulis null atau default value-nya.


// PHP 7   harus nulis semua parameter meski cuma mau set yang terakhir
$html = str_replace('search', 'replace', $string, $count);

// PHP 8   bisa langsung sebut nama parameter yang mau diisi
$html = str_replace(
    search: 'hello',
    replace: 'world', 
    subject: $string
);

// Contoh di function sendiri
function createUser(
    string $name,
    string $email = '',
    int $age = 0,
    bool $active = true,
    string $role = 'member'
): array {
    return compact('name', 'email', 'age', 'active', 'role');
}

// Skip email dan age, langsung set active dan role
$user = createUser(
    name: 'Budi',
    active: false,
    role: 'admin'
);

Ini sangat membantu kalau kamu punya function dengan banyak parameter opsional. Kode jadi lebih jelas karena pembaca langsung tahu parameter mana yang diisi.

Match Expression Switch yang Lebih Bersih

match itu versi upgrade dari switch. Return value langsung, strict comparison (pakai ===), dan syntax-nya lebih ringkas.


// PHP 7   switch, ribet
$statusText = '';
switch ($statusCode) {
    case 200:
    case 301:
        $statusText = 'OK';
        break;
    case 404:
        $statusText = 'Not Found';
        break;
    case 500:
        $statusText = 'Server Error';
        break;
    default:
        $statusText = 'Unknown';
}

// PHP 8   match, simpel
$statusText = match($statusCode) {
    200, 301 => 'OK',
    404 => 'Not Found',
    500 => 'Server Error',
    default => 'Unknown',
};

// Bisa juga dengan expression
$size = match(true) {
    $bytes < 1024 => $bytes . ' B',
    $bytes < 1048576 => round($bytes / 1024, 1) . ' KB',
    $bytes < 1073741824 => round($bytes / 1048576, 1) . ' MB',
    default => round($bytes / 1073741824, 2) . ' GB',
};

Yang bikin match lebih aman: dia pakai strict comparison. Jadi match(0) tidak akan match dengan string 'hello' masalah yang sering terjadi di switch karena loose comparison.

Union Types dan Intersection Types

PHP 8.0 introduce Union Types, dan 8.1 nambah Intersection Types. Ini bikin type declaration lebih fleksibel tapi tetap ketat.


// Union Types   parameter bisa tipe A ATAU tipe B
function formatNumber(int|float $number): string {
    return number_format($number, 2, '.', ',');
}

function processId(int|string $id): void {
    // Kalau string, convert ke int dulu
    $id = is_string($id) ? (int) $id : $id;
    echo "Processing ID: {$id}";
}

// Intersection Types (PHP 8.1)   harus implement SEMUA interface
interface Loggable {
    public function toLog(): string;
}

interface Cacheable {
    public function getCacheKey(): string;
}

function store(Loggable&Cacheable $item): void {
    echo $item->toLog();
    echo $item->getCacheKey();
}

// DNF Types (PHP 8.2)   kombinasi union dan intersection
function handle((Countable&Iterator)|array $items): void {
    // Bisa array ATAU object yang implement Countable DAN Iterator
}

Kalau kamu pakai IDE seperti PHPStorm, Union Types dan Intersection Types bikin autocomplete jadi lebih akurat. Dan kalau ada type mismatch, error langsung ketangkep sebelum runtime.

Enums Konstanta yang Lebih Keren

Sebelum PHP 8.1, kalau mau bikin tipe yang terbatas (misal status order), biasanya pakai class dengan konstanta. Sekarang ada enum yang purpose-built untuk ini.


// PHP 8.1   Backed Enum
enum OrderStatus: string {
    case Pending = 'pending';
    case Processing = 'processing';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
    case Cancelled = 'cancelled';
}

// Pakai di function
function updateStatus(OrderStatus $status): void {
    echo "Order status: " . $status->value;
}

updateStatus(OrderStatus::Shipped); // OK
// updateStatus('shipped'); // Error! Type safety

// Enum bisa punya method
enum Color: string {
    case Red = '#ff0000';
    case Green = '#00ff00';
    case Blue = '#0000ff';

    public function label(): string {
        return match($this) {
            self::Red => 'Merah',
            self::Green => 'Hijau',
            self::Blue => 'Biru',
        };
    }
}

echo Color::Red->label(); // "Merah"
echo Color::Red->value;   // "#ff0000"

Enum juga bisa di-serialize ke database tanpa masalah karena backed enum punya value yang bisa disimpan sebagai string atau integer.

Readonly Properties dan Readonly Classes

PHP 8.1 bikin property yang cuma bisa diisi sekali cocok untuk immutable objects. PHP 8.2 extend ke seluruh class.


// Readonly Properties (PHP 8.1)
class UserDTO {
    public function __construct(
        public readonly string $name,
        public readonly string $email,
        public readonly int $age,
    ) {}
}

$user = new UserDTO(name: 'Budi', email: '[email protected]', age: 25);
echo $user->name; // "Budi"
// $user->name = 'Joko'; // Error! Cannot modify readonly property

// Readonly Class (PHP 8.2)   semua property jadi readonly
readonly class Point {
    public function __construct(
        public float $x,
        public float $y,
        public float $z = 0.0,
    ) {}
}

$p = new Point(1.0, 2.0, 3.0);
// $p->x = 5.0; // Error!

Ini bagus banget untuk DTOs (Data Transfer Objects) dan value objects. Kamu bisa jamin data tidak berubah setelah object dibuat.

Fibers Async yang Lebih Natural

Fibers di PHP 8.1 itu cooperative multitasking. Mirip dengan generator/yield, tapi lebih powerful. Ini yang dipakai framework kayak Swoole dan ReactPHP di balik layar.


$fiber = new Fiber(function(): void {
    $value = Fiber::suspend('fiber pause di sini');
    echo "Fiber lanjut dengan: {$value}\n";
});

// Mulai fiber
$result = $fiber->start();
echo "Output dari suspend: {$result}\n";

// Lanjutkan fiber dengan mengirim nilai
$fiber->resume('data dari luar');

// Contoh lebih praktis   simulating async
class AsyncTask {
    private Fiber $fiber;
    
    public function __construct(callable $task) {
        $this->fiber = new Fiber($task);
    }
    
    public function run(): mixed {
        return $this->fiber->start();
    }
    
    public function continue(mixed $value = null): mixed {
        return $this->fiber->resume($value);
    }
}

$task = new AsyncTask(function() {
    echo "Step 1: Fetching data...\n";
    $data = Fiber::suspend('waiting for data');
    echo "Step 2: Got {$data}\n";
    return "Done!";
});

echo $task->run() . "\n";     // "waiting for data"
echo $task->continue('user_data') . "\n"; // "Done!"

Kalau kamu butuh benar-benar async di production, biasanya pakai library seperti AMP atau ReactPHP yang build di atas Fibers.

Constructor Promotion Shortcut yang Elegan

Fitur ini sebenarnya dari PHP 8.0, tapi belum semua orang pakai. Bisa bikin kode class jadi jauh lebih pendek.


// PHP 7   tulis property + assign di constructor, 12 baris
class Product {
    private string $name;
    private float $price;
    private int $stock;
    private bool $active;

    public function __construct(string $name, float $price, int $stock, bool $active) {
        $this->name = $name;
        $this->price = $price;
        $this->stock = $stock;
        $this->active = $active;
    }
}

// PHP 8   constructor promotion, 8 baris (hemat 4 baris!)
class Product {
    public function __construct(
        private string $name,
        private float $price,
        private int $stock,
        private bool $active = true,
    ) {}
}

// Bisa dikombinasikan dengan readonly
class OrderItem {
    public function __construct(
        public readonly string $productName,
        public readonly int $quantity,
        public readonly float $unitPrice,
    ) {}

    public function subtotal(): float {
        return $this->quantity * $this->unitPrice;
    }
}

Null Safety Operator dan Named Arguments Combo

PHP 8.0 punya nullsafe operator ?-> yang bikin chaining null checks lebih bersih.


// PHP 7   verbose null checking
$country = null;
if ($user !== null) {
    if ($user->getAddress() !== null) {
        if ($user->getAddress()->getCity() !== null) {
            $country = $user->getAddress()->getCity()->getCountry();
        }
    }
}

// PHP 8   nullsafe operator
$country = $user?->getAddress()?->getCity()?->getCountry();

// Kombinasi dengan named arguments
class UserService {
    public function findUser(int $id): ?User {
        return $this->repository->findById($id);
    }
}

$service = new UserService();
// Chain + named args
$name = $service?->findUser(id: 42)?->getProfile()?->displayName;

Fitur PHP 8.2 dan 8.3 yang Sering Terlewat

PHP 8.2 dan 8.3 bawa beberapa fitur kecil tapi berguna:

  • Disjunctive Normal Form (DNF) Types (8.2): Kombinasi union dan intersection types, misal (A&B)|C
  • Constants in Traits (8.2): Trait sekarang bisa punya konstanta
  • Dynamic Properties Deprecated (8.2): Harus pakai #[\AllowDynamicProperties] secara eksplisit
  • json_validate() (8.3): Validasi JSON tanpa decode lebih cepat dari json_decode + json_last_error
  • Typed Class Constants (8.3): Konstanta sekarang bisa diberi tipe
  • #[Override] Attribute (8.3): Pastikan method benar-benar override parent class

// json_validate (PHP 8.3)   cek JSON valid tanpa decode
$jsonString = '{"name": "Budi", "age": 25}';

// Cara lama
$result = json_decode($jsonString);
$isValid = json_last_error() === JSON_ERROR_NONE;

// PHP 8.3   satu baris
$isValid = json_validate($jsonString); // true

// Typed Class Constants (PHP 8.3)
interface HasStatus {
    const string STATUS_ACTIVE = 'active';
    const string STATUS_INACTIVE = 'inactive';
}

// #[Override] Attribute (PHP 8.3)
class BaseRepository {
    public function findById(int $id): ?object {
        return null;
    }
}

class UserRepository extends BaseRepository {
    #[\Override]
    public function findById(int $id): ?User {
        return $this->model->find($id);
    }
}

Named Arguments untuk Built-in Functions

Salah satu use case named arguments yang paling sering saya pakai: built-in PHP functions yang punya banyak parameter.


// Tanpa named arguments   harus ingat urutan parameter
$clean = filter_var($input, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);

// Dengan named arguments   lebih jelas
$clean = filter_var(
    value: $input,
    filter: FILTER_SANITIZE_EMAIL,
    options: FILTER_FLAG_NO_ENCODE_QUOTES
);

// Array functions
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

$chunked = array_chunk(
    array: $data,
    length: 3,
    preserve_keys: true
);

// String functions
$truncated = mb_strimwidth(
    string: $longText,
    start: 0,
    width: 100,
    trim_marker: '...'
);

Tips Upgrade dari PHP 7.x ke 8.x

Kalau kamu masih di PHP 7.x dan mau upgrade, ini checklist yang biasa saya pakai:

  • Cek compatibility: Pakai tool phpcompatinfo atau phpstan level tinggi untuk scan kode lama
  • Update dependencies: Pastikan semua package di composer.json support PHP 8. Jalankan composer update
  • Cek deprecated features: each(), create_function(), dan beberapa fungsi lain sudah dihapus
  • Test di staging dulu: Jangan langsung production. Pasang PHP 8.x di staging environment dan jalankan full test suite
  • Manfaatkan fitur baru bertahap: Mulai dari yang paling simpel constructor promotion, match expression, named arguments. Nanti naik ke enums dan fibers

// Cek versi PHP saat ini
echo PHP_VERSION; // 8.3.x

// Cek fitur yang tersedia
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
    echo "Enums tersedia!";
}

// composer.json   set minimum PHP version
{
    "require": {
        "php": ">=8.1",
        "laravel/framework": "^10.0"
    }
}

Perbandingan Performa PHP 7.4 vs 8.x

Bukan cuma fitur, PHP 8.x juga bawa peningkatan performa yang signifikan berkat JIT compiler dan optimasi internal:

  • PHP 8.0: JIT compiler peningkatan ~10-15% untuk CPU-intensive tasks (bukan untuk web request biasa)
  • PHP 8.1: Fiber support, readonly properties overhead minimal tapi kode lebih aman
  • PHP 8.2: Optimasi memory usage, readonly classes hemat RAM ~5-8%
  • PHP 8.3: Faster json_validate(), improved randomizer peningkatan kecil tapi konsisten

Untuk web request biasa, perbedaan performa PHP 7.4 ke 8.3 sekitar 5-10%. Tapi kalau kamu punya long-running process (queue worker, websocket server), JIT compiler di PHP 8.x bisa kasih peningkatan sampai 20-30%.

Saran saya: kalau masih di PHP 7.4, segera upgrade ke minimal PHP 8.1. Support PHP 7.4 sudah end-of-life sejak November 2022 artinya tidak ada lagi security patch. PHP 8.1 pun minimal sampai akhir 2024 untuk security fixes.


You may also like


0 Comments


Leave a Reply

Comments with links or spam keywords will be rejected.
Scroll to Top