Tips Memanggil Model Secara Dinamis

foto Dali Kewara oleh @dalikewara
11 bulan yang lalu
Hai... Saya akan membagi tips bagi pengguna framework seperti CodeIgniter, Laravel, atau bahkan Janggelan. Kamu yang sedang mengembangkan aplikasi dengan berbasis konsep MVC, pasti sangat berhubungan erat dengan yang namanya Model, apalagi kalau aplikasi kamu berhubungan dengan Database. Di Laravel, umumnya kita memanggil Model dengan menginisialisasi Object dari Modelnya, dan kita perlu menggunakan Namespace sebagai index dari identitas si Model. Jika di Controller, akan seperti ini: Misal nama Modelnya adalah User:
<?php namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;

class MyController extends Controller
{
    function __construct()
    {
        $user = new User;
    }
}
Sangat bersih dan elegan, di Janggelan juga sama cara pemanggilan Modelnya, hanya beda Namespace. Tapi, yang jadi masalah, bagaimana jika pada suatu kondisi, Controller tersebut membutuhkan banyak Model, misal 6 Model. Apakah kita harus memanggilnya satu persatu? Kayak gini:
<?php namespace App\Http\Controllers;

use App\User;
use App\Content;
use App\Category;
use App\Tag;
use App\Post;
use App\Comment;
use App\Http\Controllers\Controller;

class MyController extends Controller
{
    function __construct()
    {
        $user = new User;
        $content = new Content;
        $category = new Category;
        $tag = new Tag;
        $post = new Post;
        $comment = new Comment;
    }
}
Jawabannya iya, dan tidak. Biasanya kita memang akan memanggil setiap Model satu persatu, namun tentu saja itu akan menimbulkan beban yang berat saat PHP mengakses Controller tersebut. Ada cara yang lebih dinamis dan efisien untuk memanggil sebuah Model, kita akan menggunakan Magic Function bawaan PHP, yaitu __get(). Okeh, pertama, kita buat sebuah Controller baru, kita kasih nama saja ModelConfig:
<?php namespace App\Http\Controllers;

// Nggak perlu meng-extends Base Controller
class ModelConfig
{
    function __get($param)
    {
        // Kita buat dulu Namespace Modelnya, berdasarkan data $param
        // $param disini adalah nama Model.
        // Kenapa saya pakai tanda ' untuk string bukannya " ?
        // Soalnya tanda ' eksekusinya lebih cepat ketimbang ".
        // Jika Namespace tidak sesuai, silahkan dirubah sendiri.
        // Oh iya, kita tidak bisa memakai tanda \ secara langsung,
        // jadi harus dibuat \\.
        $namespace = '\\App\\' . $param;
        
        // Setelah Namespace berhasil dibuat, baru kita akan membuat Object Modelnya
        // Berdasarkan $namespace yang kita bikin.
        // Object Modelnya nanti bakal langsung diisikan kedalam variable property $this->$param
        $this->$param = new $namespace;

        // Kita return, supaya Modelnya bisa mengirim nilai.
        return $this->$param;
    }
}
Nah, sekarang kita tinggal gunakan Controller ModelConfig tersebut ke dalam Controller kita:
<?php namespace App\Http\Controllers;

use App\Http\Controllers\ModelConfig;
use App\Http\Controllers\Controller;

class MyController extends Controller
{
    private $model;
    
    public $user, $content, $category, $tag;

    function __construct()
    {
        $this->model = new ModelConfig;

        // Nah, selesai. Sekarang, bagaimana cara memanggil Modelnya?
        // Tinggal seperti ini:
        $this->user = $this->model->User;
        $this->content = $this->model->Content;
        $this->category = $this->model->Category;
        $this->tag = $this->model->Tag;
    }
}
Jauh lebih bersih bukan? Kita tidak perlu memanggil Model satu persatu, kita bisa memanggil berapapun banyaknya jumlah Model hanya dengan satu konfigurasi ModelConfig. Dan, saya yakin eksekusinya bakal jauh lebih cepat. Kenapa? Karena Magic Function __get() hanya akan bekerja jika kita memanggil variable property yang tidak terdefinisi sebelumnya. Jadi ketika kita memanggil Model, misal:
$this->model->User;
Magic Function __get() akan berjalan, karena variable property User tidak terdefinisi di dalam class ModelConfig. Nah, di ModelConfig, setelah Magic Function __get() di jalankan, kita langsung mendefinisikan variable tersebut:
$this->$param = new $namespace;
Artinya, seperti ini:
// Pertama kali memanggil Model User
// function __get() dijalankan karena variable property User belum terdefinisi
$this->model->User;

// Tapi, ketika memanggil atau menggunakan Model User yang sama untuk kedua kalinya,
// function __get() tidak akan dijalankan karena variable property User
// sudah didefiniskan pada saat pemanggilan yang pertama.
// $this->$param = new $namespace;
$this->model->User->All();
Cara ini saya terapkan pada aplikasi Martabak yang saya buat dengan menggunakan framework Janggelan. Saya belum mencobanya di CodeIgniter ataupun Laravel. Tapi, seharusnya hasilnya akan sama dan berhasil. Monggo, silahkan di coba. Kalau ada masalah atau kurang jelas, silahkan konfirmasi di kolom komentar.
Jawaban
foto Syaiful Nopi oleh @NPsyaiful
6 bulan yang lalu
saya ada kasus, di mana kita ingin menampilkan lebih dari satu tabel dalam satu halaman web, dalam pemikiran saya cara nya adalah dengan memanggil banyak function dalam sekali eksekusi atau route dalam suatu controller tertentu, namum bagaimana cara penerapannya, apakah cara diatas bisa di terapkan?

Login untuk diksusi di forum sekolah koding