Autoloading

Autoloader SPL dan pemetaan PSR-4.

Daftar isi

Autoloading adalah mekanisme pemuatan berkas kelas secara otomatis pada saat kelas itu pertama kali digunakan, sehingga daftar require_once yang panjang dan rentan tidak lengkap tidak perlu ditulis lagi. Topik ini membahas autoloader SPL (Standard PHP Library) yang didaftarkan dengan spl_autoload_register, kemudian memperluasnya menjadi pemetaan PSR-4 yang menghubungkan namespace dengan folder. Setelah membaca, penambahan kelas baru tidak lagi menyentuh kode pemanggilnya sama sekali.

Kelas contoh dan daftar require manual#

Tiga kelas berikut menyimpan data arsip sederhana. Seluruh kelasnya ditempatkan di dalam subfolder kelas/, dan setiap kelas menempati satu berkas dengan nama yang sama dengan nama kelasnya.

php Tugas.php
<?php

declare(strict_types=1);

class Tugas
{
    public function __construct(public string $judul)
    {
    }

    public function label(): string
    {
        return "Tugas arsip: {$this->judul}";
    }
}
php Laporan.php
<?php

declare(strict_types=1);

class Laporan
{
    public function __construct(
        public string $periode,
        public int $jumlahArsip,
    ) {
    }

    public function ringkasan(): string
    {
        return "Laporan {$this->periode}: {$this->jumlahArsip} arsip tercatat";
    }
}
php Pengingat.php
<?php

declare(strict_types=1);

class Pengingat
{
    public function __construct(public string $pesan)
    {
    }

    public function kirim(): string
    {
        return "Pengingat: {$this->pesan}";
    }
}
bash
# kumpulkan kelas ke dalam subfolder kelas/
mkdir -p kelas
cp Tugas.php Laporan.php Pengingat.php kelas/

Tanpa autoloader, skrip yang menggunakan ketiga kelas tersebut wajib memuat setiap berkasnya secara eksplisit sebelum kelas dipakai.

php daftar-tugas.php
<?php

declare(strict_types=1);

require_once 'kelas/Tugas.php';
require_once 'kelas/Laporan.php';
require_once 'kelas/Pengingat.php';

$tugas = new Tugas('Tulis laporan bulanan');
$laporan = new Laporan('November 2026', 42);
$pengingat = new Pengingat('Kumpulkan laporan sebelum Jumat');

echo $tugas->label(), "\n";
echo $laporan->ringkasan(), "\n";
echo $pengingat->kirim(), "\n";
text Keluaran
Tugas arsip: Tulis laporan bulanan
Laporan November 2026: 42 arsip tercatat
Pengingat: Kumpulkan laporan sebelum Jumat

Programnya berjalan benar, tetapi daftar require_once di atasnya menjadi muatan tambahan yang tumbuh seiring proyek. Setiap kelas baru menuntut satu baris baru, dan skrip lain yang memakai kombinasi kelas berbeda memerlukan daftarnya sendiri. Kebutuhan untuk menyusun daftar itulah yang dihilangkan oleh autoloading.

Mendaftarkan autoloader dengan spl_autoload_register#

Fungsi spl_autoload_register() mendaftarkan fungsi callback yang dipanggil PHP ketika kelas yang diminta belum terdefinisi. Fungsi tersebut menerima nama kelas yang sedang dicari, lalu tugasnya adalah menyertakan berkas yang mendefinisikannya. Apabila setelah panggilan tersebut kelasnya masih tidak ada, PHP menampilkan error class not found.

Autoloader di bawah ini menerapkan konvensi sederhana, yaitu nama kelas diterjemahkan menjadi jalur berkas kelas/NamaKelas.php. Pemeriksaan is_file() mencegah warning muncul ketika berkas kelas yang dicari tidak tersedia.

php coba-spl.php
<?php

declare(strict_types=1);

spl_autoload_register(function (string $kelas): void {
    $berkas = 'kelas/' . $kelas . '.php';
    if (is_file($berkas)) {
        include $berkas;
    }
});

var_dump(class_exists('Tugas'));

$tugas = new Tugas('Tulis laporan bulanan');
echo $tugas->label(), "\n";
echo (new Laporan('November 2026', 42))->ringkasan(), "\n";

var_dump(class_exists('PenghitungPiket'));
text Keluaran
bool(true)
Tugas arsip: Tulis laporan bulanan
Laporan November 2026: 42 arsip tercatat
bool(false)

Baris pertama keluaran bernilai true karena class_exists() memicu autoloader, berkas kelas/Tugas.php disertakan, dan kelasnya pun terdefinisi. Baris bool(false) di akhir memperlihatkan sisi lain dari mekanisme yang sama: kelas PenghitungPiket tidak ditemukan, autoloader dijalankan tetapi tidak menemukan berkasnya, sehingga class_exists() melaporkan false tanpa menghentikan program. Perhatikan juga bahwa skrip di atas tidak memuat satu pun require_once untuk ketiga kelasnya.

Pemetaan PSR-4 dari namespace ke folder#

Konvensi satu kelas satu berkas menjadi standar resmi pada PSR-4, yaitu rekomendasi PHP-FIG yang menetapkan cara autoloader menemukan berkas dari nama kelas. Aturannya menautkan awalan namespace ke sebuah folder. Nama kelas yang diminta dicocokkan dengan awalan tersebut, bagian sisanya menjadi jalur subfolder, dan segmen terakhirnya menjadi nama berkas. Skema ini memanfaatkan namespace, karena pemetaan membutuhkan nama kelas yang terstruktur.

Dua kelas berikut hidup di namespace ArsipKegiatan, sehingga menurut pemetaan PSR-4 dengan awalan ArsipKegiatan\ menuju folder kelas/, kelas Dokumen wajib berada di berkas kelas/Dokumen.php.

php Dokumen.php
<?php

declare(strict_types=1);

namespace ArsipKegiatan;

class Dokumen
{
    public function __construct(private string $judul)
    {
    }

    public function judul(): string
    {
        return "Dokumen: {$this->judul}";
    }
}
php Folder.php
<?php

declare(strict_types=1);

namespace ArsipKegiatan;

class Folder
{
    private array $dokumen = [];

    public function __construct(private string $nama)
    {
    }

    public function tambah(Dokumen $dokumen): void
    {
        $this->dokumen[] = $dokumen;
    }

    public function nama(): string
    {
        return $this->nama;
    }

    public function jumlahDokumen(): int
    {
        return count($this->dokumen);
    }
}
bash
# salin kelas ber-namespace ke folder pemetaannya
cp Dokumen.php Folder.php kelas/

Autoloader berikut memeriksa awalan namespace sebelum menerjemahkan nama kelas. Sub-namespace ditulis dengan garis miring terbalik, sehingga autoloader menukar pemisah tersebut menjadi garis miring biasa agar sesuai dengan struktur folder.

php coba-psr4.php
<?php

declare(strict_types=1);

spl_autoload_register(function (string $kelas): void {
    $awalan = 'ArsipKegiatan\\';
    if (str_starts_with($kelas, $awalan)) {
        $namaRelatif = substr($kelas, strlen($awalan));
        $berkas = 'kelas/' . str_replace('\\', '/', $namaRelatif) . '.php';
        if (is_file($berkas)) {
            include $berkas;
        }
    }
});

$dokumen = new ArsipKegiatan\Dokumen('Sertifikat pelatihan 2024');
$folder = new ArsipKegiatan\Folder('Arsip 2024');
$folder->tambah($dokumen);

echo $dokumen->judul(), "\n";
echo $folder->nama(), ': ', $folder->jumlahDokumen(), ' dokumen', "\n";
text Keluaran
Dokumen: Sertifikat pelatihan 2024
Arsip 2024: 1 dokumen

Kedua kelas di atas dimuat tanpa satu pun require_once, cukup dengan mengikuti pemetaan awalan namespace ke folder. Diagram berikut merangkum aturan yang sama.

Pemetaan PSR-4nama kelas dimintaArsipKegiatan\Dokumenbuang awalanjalur berkaskelas/Dokumen.phpAwalan namespace berakhir dengan backslash, sedangkan segmen sisanya menjadi folder di bawah folder pemetaandan nama kelas terakhir menjadi nama berkasnya.
Pemetaan PSR-4 dari nama kelas ke berkas

Autoloader buatan sendiri seperti di atas berlaku untuk proyek kecil. Untuk proyek yang memakai pustaka pihak ketiga, pemetaan PSR-4 dikelola oleh Composer melalui kunci autoload di berkas composer.json, dan autoloader yang dihasilkannya mencakup seluruh dependensi sekaligus.

Kesalahan umum#

  • Membiarkan autoloader menyertakan berkas yang tidak ada. Tanpa pemeriksaan, include terhadap jalur yang tidak ditemukan memunculkan warning setiap kali kelas yang tidak ada diperiksa, misalnya melalui class_exists(). Perbaikannya adalah menambahkan is_file() sebelum include, sehingga pemanggilan class_exists() terhadap kelas yang tidak ada tetap mengembalikan false tanpa memunculkan warning.
  • Nama berkas dan nama kelas tidak seragam. Autoloader menerjemahkan nama kelas menjadi nama berkas, sehingga kelas Dokumen yang tersimpan di dokumen.php tidak akan dimuat. Seragamkan nama berkas dengan nama kelas termasuk kapitalisasinya.
  • Mengubah nama kelas tanpa memperbarui pemetaannya. Penggantian nama kelas tanpa mengubah nama berkasnya menyebabkan error class not found pada saat kelas diinstansiasi, bukan pada saat berkas disunting. Jalankan program setelah setiap perubahan nama untuk menangkapnya sejak dini.
  • Mengira spl_autoload_register menggantikan require untuk berkas non-kelas. Autoloader hanya terpicu ketika PHP mencari definisi kelas, interface, atau trait. Berkas konfigurasi dan templat tetap dimuat dengan require seperti biasa.

Ringkasan#

  • spl_autoload_register() mendaftarkan fungsi yang dipanggil PHP saat kelas yang diminta belum terdefinisi, dan tugasnya menyertakan berkas yang mendefinisikan kelas tersebut.
  • Pemeriksaan is_file() menjaga autoloader tetap senyap terhadap nama kelas yang tidak ada, sehingga class_exists() dapat mengembalikan false tanpa warning.
  • PSR-4 memetakan awalan namespace ke sebuah folder, dengan segmen namespace sisanya menjadi subfolder dan nama kelas menjadi nama berkas.
  • Composer mengelola pemetaan PSR-4 untuk proyek dan seluruh dependensinya melalui kunci autoload di composer.json.

Referensi#