Kita sudah memahami mengapa namespaces ada; sekarang saatnya menulisnya dengan benar. Deklarasi namespace tampak sederhana — satu baris namespace di bagian atas berkas — tetapi PHP menjalankan aturan ketat soal penempatannya, dan ada dua sintaks resmi yang perlu dikenali. Chapter ini membahas deklarasi dasar, konstanta __NAMESPACE__, sintaks kurung kurawal, larangan dan alasan di balik kebiasaan satu namespace per berkas, hingga penyusunan sub-namespace bertingkat seperti App\Domain\Model.

Deklarasi Dasar #

Bentuk paling umum adalah pernyataan namespace diikuti nama dan titik koma, ditulis sebagai statement pertama setelah tag pembuka PHP. Seluruh class, interface, function, dan const setelahnya menjadi milik namespace tersebut:

php
<?php

namespace App\Domain\Model;

class Pengguna {}

interface Repository {}

function buatPengguna(string $nama): Pengguna
{
    return new Pengguna();
}

const VERSI = "1.0";

echo __NAMESPACE__ . "\n";
echo Pengguna::class . "\n";
echo Repository::class . "\n";

$budi = buatPengguna("Budi");
echo $budi::class . "\n";
echo VERSI . "\n";

Output yang Dihasilkan:

text
App\Domain\Model
App\Domain\Model\Pengguna
App\Domain\Model\Repository
App\Domain\Model\Pengguna
1.0

Mari kita bedah hasilnya baris per baris:

  1. Baris 3 (namespace App\Domain\Model;): namespace bertingkat tiga segmen. Segmen dipisah backslash (\) dan setiap segmen mengikuti konvensi huruf pertama kapital.
  2. Baris 5-7: class Pengguna dan interface Repository otomatis tinggal di App\Domain\Model — nama lengkapnya App\Domain\Model\Pengguna dan App\Domain\Model\Repository.
  3. Baris 9-12: function juga terpengaruh; buatPengguna() yang dipanggil tanpa namespace dari berkas ini menunjuk versi lokal App\Domain\Model\buatPengguna().
  4. Baris 14: konstanta yang dideklarasikan dengan const di level berkas ikut menjadi milik namespace (App\Domain\Model\VERSI).
  5. Baris 16 (__NAMESPACE__): konstanta ajaib ini berisi nama namespace saat ini sebagai string — hasil cetaknya App\Domain\Model. Konstanta ini berguna untuk membangun nama lengkap secara dinamis.
  6. Baris 17-18 (Pengguna::class): konstanta ::class menghasilkan nama lengkap class sebagai string, jauh lebih aman daripada mengetik nama lengkap secara manual yang rawan typo.
  7. Baris 20-21 ($budi::class): ::class juga bisa dipanggil dari variabel objek; hasilnya tetap nama lengkap class instance tersebut.

Perlu dicatat bahwa namespace hanya mengatur simbol-simbol tersebut — variable, superglobal seperti $_GET, dan fungsi bawaan PHP (strlen(), array_map()) tidak termasuk. Aturan resolusi nama lengkap untuk fungsi bawaan ini kita bahas tuntas pada chapter Namespace Resolution .

Sintaks Alternatif dengan Kurung Kurawal #

PHP menyediakan bentuk kedua: nama namespace diikuti blok kode dalam kurung kurawal. Semua kode di dalam kurung menjadi milik namespace tersebut:

php
<?php

namespace App\Util {
    class Pembersih
    {
        public static function teks(string $input): string
        {
            return trim($input);
        }
    }
}

namespace App {
    echo \App\Util\Pembersih::teks("  Halo  ") . "!\n";
    echo __NAMESPACE__ . "\n";
}

Output yang Dihasilkan:

text
Halo!
App

Tiga hal membedakan bentuk ini dari versi titik koma:

  1. Tanpa titik koma: deklarasi namespace App\Util { langsung membuka blok; kode namespace berada di antara kurung kurawal.
  2. Blok namespace App kedua (baris 13-16) berjalan dalam namespace App — di sinilah letak kegunaan utamanya: beberapa blok namespace bisa ditulis dalam satu berkas, misalnya untuk berkas contoh singkat atau skrip pengujian kecil.
  3. Baris 14 (\App\Util\Pembersih::teks(...)): akses class dari namespace lain memakai nama lengkap berawalan backslash, sama seperti yang kita lihat pada chapter sebelumnya.

Satu berkas tidak boleh mencampur kedua gaya — pilih seluruhnya gaya titik koma atau seluruhnya gaya kurung kurawal. Kehadiran HTML di luar blok kurung kurawal juga sah pada gaya ini; gaya kurung bahkan menyediakan blok khusus namespace { ... } tanpa nama untuk kode global di berkas yang sama.

Beberapa Namespace dalam Satu Berkas #

Dengan gaya titik koma pun, PHP tetap mengizinkan lebih dari satu deklarasi namespace dalam satu berkas — setiap deklarasi baru menutup namespace sebelumnya:

php
<?php

namespace Modul\Autentikasi;

class Sesi {}

namespace Modul\Blog;

class Sesi {}

echo Sesi::class . "\n";

Output yang Dihasilkan:

text
Modul\Blog\Sesi

Dua class bernama Sesi sama-sama sah: yang pertama menjadi Modul\Autentikasi\Sesi, yang kedua Modul\Blog\Sesi. Pada baris terakhir, nama Sesi::class di-resolve terhadap namespace yang sedang aktif — Modul\Blog — sehingga hasilnya Modul\Blog\Sesi.

Kemampuan ini nyata tetapi jarang tepat dipakai:

Penempatan Deklarasi yang Wajib di Awal #

Aturan penempatan namespace ketat: deklarasi harus menjadi statement pertama dalam berkas. Statement lain sebelumnya — termasuk echo — langsung memicu fatal error:

php
<?php

echo "Memuat modul...\n";

namespace App\Util;

Output yang Dihasilkan:

text

Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in /home/z/my-project/php-course/content/php/namespaces-dan-autoloading/namespace-declarations/.verify_tmp.php on line 5

Pesan Namespace declaration statement has to be the very first statement or after any declare call in the script menjelaskan pengecualiannya sekaligus: satu-satunya yang boleh mendahului namespace adalah blok declare(). Inilah urutan yang benar ketika proyek Anda menuntut strict_types:

php
<?php

declare(strict_types=1);

namespace App\Util;

class Pembersih {}

Sub-Namespace dan Hierarki #

Nama namespace bisa bertingkat sedalam yang dibutuhkan proyek: App\Domain\Model terdiri dari tiga segmen dengan App sebagai akar. Praktik umum menata segmen berdasarkan tanggung jawabnya:

text
App\
├── Domain\
│   ├── Model\          → namespace App\Domain\Model
│   └── Repository\     → namespace App\Domain\Repository
└── Layanan\
    └── Notifikasi\     → namespace App\Layanan\Notifikasi

Struktur seperti ini memberi dua manfaat nyata. Pertama, nama class tetap pendek di dalam konteksnya — cukup Pengguna di dalam App\Domain\Model, tanpa perlu PenggunaModel atau ModelPengguna. Kedua, segmen mengomunikasikan wilayah kerja sebuah class begitu dibaca: kode yang menyentuh App\Domain\Repository jelas berurusan dengan penyimpanan data, bukan tampilan. Konvensi penulisan segmen mengikuti pola yang sama dengan nama class: setiap segmen diawali huruf kapital tanpa pemisah tambahan.

PHP sendiri tidak memaksa nama namespace mengikuti folder di disk — keduanya independen secara teknis. Namun standar PSR-4 yang kita bahas pada chapter PSR-4 Autoloading menyatukan keduanya: nama lengkap class menentukan lokasi berkasnya, sehingga hierarki namespace dan hierarki folder tumbuh sebagai cermin satu sama lain.

Ringkasan #

Deklarasi namespace punya dua sintaks resmi — titik koma untuk berkas satu-namespace, kurung kurawal untuk kasus khusus multi-namespace — dan harus menempati statement pertama berkas, hanya didahului declare(). Namespace mencakup class, interface, function, dan konstanta level berkas; konstanta __NAMESPACE__ dan ::class membantu membaca nama lengkap saat runtime; hierarki sub-namespace menjaga nama class tetap pendek sekaligus bermakna. Menulis nama lengkap berawalan backslash pada setiap pemanggilan, seperti yang kita lakukan berkali-kali di chapter ini, cepat membuat kode sesak — keyword use untuk mengimpor nama adalah solusinya, dan menjadi topik chapter Namespace Imports .

Referensi #