Standar PSR-4 Autoloader PHP

28 November 2024
Bagikan:
Standar PSR-4 Autoloader PHP

PSR-4 Autoloader adalah standar yang ditetapkan oleh PHP-FIG (PHP Framework Interoperability Group) untuk mengatur cara pemuatan otomatis (autoloading) kelas-kelas PHP. PSR-4 adalah salah satu standar autoloading yang memungkinkan pemrograman PHP lebih efisien dengan mengurangi beban pengelolaan file secara manual dan memastikan struktur direktori yang konsisten untuk kelas-kelas yang ada.

Ada beberapa point penting yang menurut saya psr-4 ini merupakan standar autoloading yang lebih modern dan fleksibel dibandingkan dengan psr-0 yakni :

  1. Namespace dan Struktur Direktori
    PSR-4 mengharuskan bahwa namespace yang ada pada sebuah kelas harus mencerminkan struktur direktori tempat kelas itu berada. Artinya, namespace pada kelas menjadi petunjuk untuk menemukan file kelas tersebut.
  2. Mapping Namespace ke Direktori 
    PSR-4 menetapkan bahwa setiap namespace yang diawali dengan nama tertentu harus dipetakan ke sebuah direktori dalam sistem file. Sebagai contoh, namespace Acme\Library mungkin dipetakan ke direktori src/Acme/Library.
  3. Konversi dari Namespace ke Nama File
    Namespace dan nama kelas dikonversi menjadi nama file. Misalnya: Namespace Acme\Library Kelas Book Maka nama file yang terkait adalah src/Acme/Library/Book.php.
  4. Tanpa Kode Manual untuk Mengimpor Kelas
    Dengan PSR-4, autoloader akan otomatis mencari dan memuat file kelas sesuai dengan aturan yang sudah ditetapkan, sehingga Anda tidak perlu lagi menggunakan require atau include secara manual.

Contoh Implementasi PSR-4

Misalkan Anda memiliki struktur direktori sebagai berikut:

/src
    /Acme
        /Library
            Book.php

Dan kelas Book di dalam namespace Acme\Library:

<?php
// src/Acme/Library/Book.php
namespace Acme\Library;
class Book {
    public function __construct() {
        echo "This is a book!";
    }
}

Nah dengan autoloader maka file tersebut akan dipanggil secara otomatis ketika dibutuhkan (mis. oleh router). Dalam praktiknya saya sering kali menggunakan autoloader bersamaan dengan php router agar setiap module atau kode yang ada pada kelas - kelas bisa dialamatkan atau dipanggil menggunakan php router

Contoh lain misal saya punya direktori kerja seperti berikut 

/app
      /Autoloader
            Psr4Autoloader.php
      /Models
     /Controllers
     /Validate
     /Helper
/views
    /html1
         main.phtml
    /html2
         main.phtml
    /html3
        main.phtml

Dengan autolder saya bisa memanggil file atau fungsi dari direktori Helper yang dibutuhkan oleh file main.phtml hanya dengan memanggil file tersebut dengan parameter seperti contoh berikut :
 

use Helper\Helper;
$app = new Helper;

Contoh Autoloader Standar PSR-4

Setidaknya ada dua buah contoh yang kita implementasikan berdasarkan refrensi dari laman github https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md 

1. Autoloader dengan spl_autoload_register

Di bawah ini adalah contoh implementasi fungsi autoload secara manual yang sesuai dengan standar PSR-4. Fungsi autoloader ini akan mencari dan memuat kelas-kelas berdasarkan namespace dan struktur direktori yang sesuai.

spl_autoload_register(function ($class) {
    // Prefix namespace proyek yang digunakan
    $prefix = 'Foo\\Bar\\';
    // Direktori dasar untuk prefix namespace
    $base_dir = __DIR__ . '/src/';
    // Mengecek apakah kelas menggunakan prefix namespace yang sesuai
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // Jika tidak, lanjutkan ke autoloader lainnya
        return;
    }
    // Ambil nama kelas relatif (setelah prefix namespace)
    $relative_class = substr($class, $len);
    // Ganti prefix namespace dengan direktori dasar dan ganti separator namespace menjadi separator direktori
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
    // Jika file ditemukan, muat file tersebut
    if (file_exists($file)) {
        require $file;
    }
});

Keterangan:

  • Fungsi spl_autoload_register mendaftarkan fungsi untuk mencari dan memuat file kelas secara otomatis.
  • Autoloader akan mencari kelas dengan namespace yang diawali dengan Foo\Bar\ dan mencari file yang sesuai di direktori /src/.
  • Jika ditemukan, file kelas tersebut akan dimuat menggunakan require.

Contoh implemntasi

new \Foo\Bar\Baz\Qux; // Mencari file /src/Baz/Qux.php

2. Autoloader multiple namespace
Di bawah ini adalah contoh implementasi autoloader yang lebih kompleks, yang mendukung banyak direktori untuk satu prefix namespace. Ini memungkinkan Anda untuk mengatur beberapa direktori untuk satu namespace.

namespace Example;
class Psr4AutoloaderClass
{
    protected $prefixes = array();
    // Mendaftarkan autoloader
    public function register()
    {
        spl_autoload_register(array($this, 'loadClass'));
    }
    // Menambahkan direktori dasar untuk namespace tertentu
    public function addNamespace($prefix, $base_dir, $prepend = false)
    {
        $prefix = trim($prefix, '\\') . '\\';  // Normalisasi prefix
        $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/'; // Normalisasi direktori dasar
        if (!isset($this->prefixes[$prefix])) {
            $this->prefixes[$prefix] = array();
        }
        if ($prepend) {
            array_unshift($this->prefixes[$prefix], $base_dir);
        } else {
            array_push($this->prefixes[$prefix], $base_dir);
        }
    }
    // Memuat kelas berdasarkan namespace
    public function loadClass($class)
    {
        $prefix = $class;
        // Menelusuri namespace untuk menemukan file yang sesuai
        while (false !== $pos = strrpos($prefix, '\\')) {
            $prefix = substr($class, 0, $pos + 1);
            $relative_class = substr($class, $pos + 1);
            // Coba memuat file yang sudah dipetakan
            $mapped_file = $this->loadMappedFile($prefix, $relative_class);
            if ($mapped_file) {
                return $mapped_file;
            }
            // Menghapus separator namespace untuk iterasi berikutnya
            $prefix = rtrim($prefix, '\\');
        }
        // Jika tidak ditemukan, kembalikan false
        return false;
    }
    // Memuat file yang dipetakan berdasarkan prefix namespace dan nama kelas relatif
    protected function loadMappedFile($prefix, $relative_class)
    {
        if (!isset($this->prefixes[$prefix])) {
            return false;
        }
        // Mencari file di direktori basis namespace
        foreach ($this->prefixes[$prefix] as $base_dir) {
            $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
            if ($this->requireFile($file)) {
                return $file;
            }
        }
        return false;
    }
    // Memeriksa apakah file ada, dan jika ada, memuatnya
    protected function requireFile($file)
    {
        if (file_exists($file)) {
            require $file;
            return true;
        }
        return false;
    }
}

Keterangan:

  • addNamespace(): Menambahkan direktori dasar untuk namespace tertentu. Dapat menambahkan beberapa direktori untuk satu namespace.
  • loadClass(): Fungsi ini berfungsi untuk menelusuri namespace dan mencoba memuat kelas yang sesuai dari direktori yang telah ditambahkan.
  • loadMappedFile(): Memetakan namespace dan nama kelas ke file yang sesuai dalam direktori dasar yang ditambahkan sebelumnya.
  • requireFile(): Mengecek apakah file kelas ada dan jika ada, akan dimuat menggunakan require.

Contoh implemnetasi :

$loader = new \Example\Psr4AutoloaderClass;
$loader->register();
// Menambahkan beberapa direktori untuk namespace Foo\Bar
$loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
$loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
// Mencoba memuat kelas
new \Foo\Bar\Qux\Quux;      // Memuat dari /path/to/packages/foo-bar/src/Qux/Quux.php
new \Foo\Bar\Qux\QuuxTest;  // Memuat dari /path/to/packages/foo-bar/tests/Qux/QuuxTest.php

Penjelasan Umum

  • PSR-4 memungkinkan Anda untuk memetakan namespace ke struktur direktori. Setiap bagian namespace yang dipisahkan oleh tanda \ akan diterjemahkan menjadi subdirektori.
  • Autoloader ini secara otomatis mencari dan memuat file kelas sesuai dengan namespace yang digunakan tanpa perlu menyertakan file secara manual.
  • Anda bisa mengonfigurasi autoloader untuk mencari kelas di berbagai direktori yang berbeda.

Kesimpulan

Implementasi PSR-4 autoloading di PHP sangat bermanfaat dalam mengelola file-file kelas secara otomatis dan terstruktur. Dengan menggunakan Composer atau implementasi manual seperti di atas, Anda dapat memastikan bahwa kelas-kelas PHP dimuat secara efisien, sesuai dengan standar yang ada, dan menghindari penggunaan require atau include secara manual di setiap file.

Standar PSR-4 Autoloader PHP | Blog Pursem.com | Pursem