โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 0 ยท Fondasi PHP & Tooling

PHP modern untuk pendatang

Kamu sudah bisa ngoding di bahasa lain. Materi ini bukan kursus pemrograman, melainkan peta cepat sintaks PHP modern yang benar-benar muncul di kode Laravel.

Sumber asli www.php.net Resmi Rangkuman ~8 menit baca

Intisari

  • Laravel 13 minimal PHP 8.3. Semua contoh di roadmap ini memakai deklarasi tipe โ€” bukan gaya PHP lama.
  • declare(strict_types=1) mengubah PHP dari "memaksa cocok" jadi "menolak yang tidak cocok". Nyalakan.
  • Constructor property promotion memangkas kelas boilerplate jadi beberapa baris โ€” Laravel memakainya di mana-mana.
  • enum, readonly, dan match menggantikan konstanta string, setter, dan switch yang bocor.
  • Yang beda dari bahasa lain: variabel selalu berawalan $, penyambung string adalah ., dan array itu list sekaligus map.

Bentuk kelas yang akan kamu tulis

Ini kelas PHP modern yang khas. Kalau kamu pernah menulis Java, TypeScript, atau Python bertipe, hampir semuanya langsung terbaca โ€” perbedaannya cuma tanda $ dan letak tipe di depan nama:

<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Invoice;

final class InvoiceTotal
{
    // Constructor property promotion: parameter sekaligus properti.
    // Tanpa ini, kamu perlu 3 baris per properti (deklarasi, parameter, assignment).
    public function __construct(
        private readonly TaxRate $tax,
        private readonly int $pembulatan = 2,
    ) {}

    public function hitung(Invoice $invoice): float
    {
        $subtotal = 0.0;

        foreach ($invoice->items as $item) {
            $subtotal += $item->harga * $item->jumlah;
        }

        return round($subtotal * (1 + $this->tax->rate()), $this->pembulatan);
    }
}
Yang mungkin asingArtinya
<?phpPenanda awal kode PHP. File yang isinya hanya PHP tidak pernah ditutup dengan ?> โ€” penutup itu penyebab klasik "headers already sent".
declare(strict_types=1)Matikan konversi tipe diam-diam. Baris pertama setelah <?php, berlaku per file.
namespace + useSama seperti package/import. Namespace wajib mengikuti struktur folder โ€” ini yang membuat autoload jalan.
private readonlyHanya bisa diisi sekali, di dalam kelas. Objek jadi tidak bisa berubah setelah dibuat.
$this->taxAkses properti. Panah -> untuk objek, :: untuk hal statik.
: floatTipe kembalian. Dengan strict_types, mengembalikan "12" di sini adalah error, bukan diam-diam dikonversi.

Array: satu tipe, dua peran

Ini perbedaan yang paling sering menjebak pendatang. PHP tidak membedakan list dan dictionary โ€” keduanya array. Yang membedakan cuma kuncinya:

$list = ['a', 'b', 'c'];                    // kunci 0, 1, 2 โ€” otomatis
$map  = ['nama' => 'Ani', 'umur' => 30];    // kunci string

$list[] = 'd';                              // append
$map['kota'] = 'Bandung';                   // set

// Cek keberadaan kunci โ€” BUKAN isset(), kalau nilainya boleh null
if (array_key_exists('kota', $map)) { /* ... */ }

// Destructuring
['nama' => $nama, 'umur' => $umur] = $map;

Jebakan isset(). isset($map['kota']) mengembalikan false kalau kuncinya ada tapi nilainya null. Untuk "apakah kuncinya ada", pakai array_key_exists(). Bug ini muncul lagi nanti saat membaca payload JSON.

Enum menggantikan konstanta string

Di Laravel, status pesanan, peran pengguna, dan jenis pembayaran hampir selalu jadi enum. Eloquent bisa melakukan cast kolom database langsung ke enum, jadi tipe ini tidak berhenti di lapisan PHP:

enum StatusPesanan: string
{
    case Menunggu  = 'menunggu';
    case Dibayar   = 'dibayar';
    case Dikirim   = 'dikirim';
    case Batal     = 'batal';

    // Enum boleh punya method โ€” ini yang membuatnya jauh lebih dari sekadar konstanta.
    public function bisaDibatalkan(): bool
    {
        return match ($this) {
            self::Menunggu, self::Dibayar => true,
            self::Dikirim, self::Batal    => false,
        };
    }
}

$status = StatusPesanan::from('dibayar');        // lempar error kalau nilainya asing
$status = StatusPesanan::tryFrom('ngawur');      // null kalau tidak dikenal

match berbeda dari switch dalam tiga hal yang penting: ia memakai perbandingan ketat (===), tidak perlu break, dan melempar error kalau tidak ada cabang yang cocok. Yang terakhir itu fitur โ€” enum baru yang lupa ditangani akan berteriak, bukan diam.

Null-safety dan operator yang sering muncul

$nama = $user?->profil?->nama;              // nullsafe: berhenti jadi null, tidak error
$kota = $data['kota'] ?? 'tidak diketahui'; // null coalescing
$hitung ??= 0;                              // isi kalau masih null
$pesan = 'Halo, ' . $nama . '!';            // titik, bukan plus

$aktif = array_filter($users, fn ($u) => $u->aktif);   // arrow fn: satu ekspresi, auto-capture
$nama  = array_map(fn ($u) => $u->nama, $users);

Titik, bukan plus. 'a' + 'b' di PHP adalah operasi aritmetika dan akan gagal. Penyambung string selalu ., dan itu juga sebabnya .= ada.

Yang boleh kamu lewati

Topik PHPKenapa dilewati di roadmap ini
mysqli_*, PDO manualEloquent dan query builder yang mengurusnya
Menempel HTML di tengah PHPBlade yang mengurus tampilan
global, variabel superglobal langsungLaravel membungkusnya jadi objek Request
Autoload manual, require berantaiComposer yang mengurusnya (materi berikutnya)
Tutorial PHP sebelum versi 8Sintaksnya berbeda cukup jauh sampai bisa menyesatkan

Latihan: tulis satu file hitung.php berisi declare(strict_types=1), satu enum StatusPesanan, dan satu fungsi bertipe yang menerima array pesanan lalu mengembalikan total yang statusnya Dibayar. Jalankan dengan php hitung.php. Lalu sengaja kirim string ke parameter int dan baca pesan errornya โ€” itu strict_types yang sedang bekerja untukmu.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.