Langsung ke konten utama

Service Container di Symfony

Project kita di symfony merupakan sekumpulan object yang saling bekerja sama untuk menyelesaikan suatu pekerjaan. Ketika kita menginstall suatu bundle, kita menambahkan obbject pada project kita. Di symfony, object-object tersebut disebut sebagai Service. Contoh beberapa Service bawaan Symfony seperti Mail, Logger, dll yang spesifik digunakan untuk melakukan tugas tertentu.

Notes : 
Untuk project latihan, silahkan download sorce code latihan dari seri tulisan symfony ini di akun github saya di https://github.com/kematjaya0/tutorial

dan untuk seri tulisan saya sebelumnya bisa dibaca di : 

Artikel resimi mengenai Service Container bisa dilihat di halaman berikut https://symfony.com/doc/current/service_container.html.

Membuat Service

Pada dasarnya semua Class yang kita tulis di dalam folder src adalah Service kecuali Entity. potongan kode dibawah ini merupakan contoh penggunaan Logger untuk melakukan pencatatan log.
<?php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;   // tambahkan class Request
use Psr\Log\LoggerInterface;                    // tambahkan class LoggerInterface
/**
 * Description of HelloController
 *
 * @author NUR HIDAYAT
 */
class HelloController {
    
    /**
     * 
     * @Route("/hello", name="hello")
     */
    public function index(LoggerInterface $logger, Request $request) // Inject class LoggerInterface dan Request sebagai parameter
    {
        $number = random_int(0, 100);
        // fungsi untuk menampilkan log
        $logger->info(date('d M Y H:i:s').' : '.$request->getClientIp().' access path => '.$request->getRequestUri());
        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}
pada kode di atas saya memasukkan interface LoggerInterface sebagai parameter function index(), secara otomatis kita bisa menggunakan object dari class Logger untuk menulis log tanpa harus melakukan inisialisasi object dengan keyword new

Membuat Service

Seperti sudah saya sebutkan sebelumnya, bahwa semua Class yang kita buat di dalam folder src adalah service kecuali folder DependencyInjection, Entity dan Class Kernel.php. Kita bisa menemukan pengaturan terkait Service pada file konfigurasi yang ada di folder config/service.yaml.
# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}'

    # ...
Kita bisa dengan mudah melakukan inject Class tanpa harus melakukan inisialisasi object karena proses inisisalisasi sudah di handle oleh Service Container dan pengaturan autowire dan autoconfigure di set dengan nilai true. 
Sebagai contoh, saya akan membuat Service berupa Class Calculator.php yang berisi fungsi-fungsi perhitungan aritmatika sederhana seperti perkalian, pembagian, penjumlahan dll yang saya tempatkan di dalam folder src/Service. 
<?php // src/Service/Calculator.php

/**
 * Description of Calculator
 *
 * @author NUR HIDAYAT
 */

namespace App\Service;

class Calculator {
    
    public function tambah($a, $b)
    {
        return $a + $b;
    }
    
    public function kurang($a, $b)
    {
        return $a - $b;
    }
    
    public function kali($a, $b)
    {
        return $a * $b;
    }
    
    public function bagi($a, $b)
    {
        return $a/$b;
    }
    
    public function percen($percen, $nilai)
    {
        return $nilai * $percen / 100;
    }
}
kemudian untuk menggunakan object dari Class Calculator, kita bisa melakukan inject di controller HelloController.php sehingga menjadi seperti berikut:
<?php //src/Controller/HelloController.php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
use App\Service\Calculator;                     // tambahkan class Calculator
/**
 * Description of HelloController
 *
 * @author NUR HIDAYAT
 */
class HelloController 
{
    
    /**
     * 
     * @Route("/hello", name="hello")
     */
    public function index(Calculator $calculator)
    {
        $a = 10;
        $b = 100;
        $number = $calculator->tambah($a, $b);
        
        return new Response(
            '<html><body>Lucky '.$a.' + '.$b.' : '.$number.'</body></html>'
        );
    }
}
Mudah bukan ? kita tidak perlu melakukan inisialisasi object secara manual. Kemudian jalankan kembali di browser sehingga jika jalan hasilnya akan seperti berikut:

untuk melihat daftar Service yang ada, kita bisa menjalankan kode berikut pada CMD:
php bin/console debug:autowiring
kurang lebih akan muncul seperti berikut.

Memanggil Service pada Service Yang Lain

Kita bisa menggunakan Service lain bawaan symfony atau buatan yang lain pada Service buatan kita dengan cara melakukan Dependency Injection pada class buatan kita. Sebagai contoh, saya akan memasukkan class LoggerInterface pada class Calculator yang baru saja kita buat. Ubah class Calculator.php sehingga menjadi seperti berikut.
<?php // src/Service/Calculator.php

/**
 * Description of Calculator
 *
 * @author NUR HIDAYAT
 */

namespace App\Service;

use Psr\Log\LoggerInterface;

class Calculator 
{
    
    private LoggerInterface $logger;
    
    public function __construct(LoggerInterface $logger) 
    {
        $this->logger = $logger;
    }
    public function tambah($a, $b)
    {
        $this->logger->info('tambah : '.$a.' + '.$b.' = '. ($a + $b)); // menggunakan logger
        return $a + $b;
    }
    
    public function kurang($a, $b)
    {
        $this->logger->info('kurang : '.$a.' - '.$b.' = '. ($a - $b)); // menggunakan logger
        return $a - $b;
    }
    
    public function kali($a, $b)
    {
        $this->logger->info('kali : '.$a.' * '.$b.' = '. ($a * $b)); // menggunakan logger
        return $a * $b;
    }
    
    public function bagi($a, $b)
    {
        $this->logger->info('bagi : '.$a.' / '.$b.' = '. ($a / $b)); // menggunakan logger
        return $a/$b;
    }
    
    public function percen($percen, $nilai)
    {
        return $nilai * $percen / 100;
    }
}
pada kode di atas, saya memasukkan class LoggerInterface sebagai parameter function __construct(), kemudian saya memanggilnya saat function tambah(), kurang(), bagi(), kali(). Tehnik ini dinamakan Dependency Injection yang bisa anda pelajari lebih lanjut pada halaman berikut https://phptherightway.com/#dependency_injection

Menggunakan Alias

Pada tulisan saya di atas, saya mencoba membuat dan memanggil Service yang kita buat dengan cara memasukkan class / inject pada service yang lain. Untuk memanggil, kita bisa juga menggunakan alias sehingga kita tidak perlu menambahkan Class Calculator yang kita buat di bagian atas Controller. Untuk membuat alias, kita buka file services.yaml yang ada di folder config. Buka dan tambahkan kode berikut di dalam tag services : 
    app.calculator: 
        public: true
        class: App\Service\Calculator
sehingga file services.yaml menjadi seperti berikut: 
# config/services.yaml

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per    class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    app.calculator: 
        public: true
        class: App\Service\Calculator
kemudian ubah controller sehingga menjadi seperti berikut: 
<?php //src/Controller/HelloController.php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; // tambahkan class Controller
/**
 * Description of HelloController
 *
 * @author NUR HIDAYAT
 */
class HelloController extends Controller
{
    
    /**
     * 
     * @Route("/hello", name="hello")
     */
    public function index()
    {
        $a = 10; 
        $b = 100;
        $calculator = $this->get('app.calculator'); 
        $number = $calculator->tambah($a, $b);
        
        return new Response(
            '<html><body>Lucky '.$a.' + '.$b.' : '.$number.'</body></html>'
        );
    }
}
pada kode di atas, saya melakukan beberapa perubahan, antara lain Class HelloController saya ubah sehingga menjadi extends ke Class Controller sehingga bisa memanggil Service Container menggunakan nama id / alias yang kita tulis di file services.yaml.

Kesimpulan

Dengan menggunakan Service Container, Controller kita bisa lebih bersih karena kita memisahkan fungsi-fungsi yang bisa dipakai ulang ke dalam Service. Kita bisa membuat beberapa fungsi seperti kirim email, upload file, atau yang lain menjadi sebuah Service sehingga bisa kita pakai ulang pada modul / Controller yang lain.

Terima kasih sudah membaca tulisan saya kali ini, semoga bermanfaat

Komentar

  1. kelinci99
    Togel Online Terpercaya Dan Games Laiinnya Live Casino.
    HOT PROMO NEW MEMBER FREECHIPS 5ribu !!
    NEXT DEPOSIT 50ribu FREECHIPS 5RB !!
    Ada Bagi2 Freechips Untuk New Member + Bonus Depositnya Loh ,
    Yuk Daftarkan Sekarang Mumpung Ada Freechips Setiap Harinya
    segera daftar dan bermain ya selain Togel ad juga Games Online Betting lain nya ,
    yang bisa di mainkan dgn 1 userid saja .
    yukk daftar di www.kelinci99.casino

    BalasHapus

Posting Komentar

Postingan populer dari blog ini

Contoh Perhitungan Algoritma Perceptron

      Melanjutkan tulisan saya sebelumnya tentang algoritma perceptron,kali ini saya akan menulis tentang conto perhitungan manual algoritma perceptron. Untuk contoh kasusnya saya menggunakan data logika AND. Cekidot.... Algoritma      Data yang kita gunakan sebagai contoh adalah data logika AND sebagai berikut: x1 x2 target 0 0 0 0 1 0 1 0 0 1 1 1       tentukan bobot awal secara acak, saya pakai contoh w1 = 0,w2 =0, learning rate = 1, bias = 0,maksimal epoh = 10. Disini saya memakai fungsi aktivasi undak biner. Epoh ke 1 Data ke satu x = {0,0}, bobot w = {0,0},b=0,target = 0 y_in = (x1*w1)+(x2*w2)+b = (0*0)+(0*0)+0 = 0 y = sign(0) = 1 karena y != target maka hitung error dan update bobot  error = target - y = 0 - 1 = -1 w1_baru = w1_lama +(learning_rate*error*x1)                = 0 + (1*(-1)*0) = 0 w2_baru = w2_lama +(learning_rate*error*x2)                = 0+(1*(-1)*0) = 0

Pemrograman Berorientasi Object - Overloading dan Overriding

       Function atau method overloading dan override adalah fitur yang sangat mendasar dan berguna dari bahasa OOP manapun. Dalam tutorial ini kita akan membahas implementasi metode overloading dan override di php. Di sini pertama kita akan membahas dasar-dasar overloading dan override. Setelah eksplorasi dasar kita akan menerapkan overloading dan override di php. Sebelum melangkah lebih jauh, saya mengasumsikan bahwa Anda memiliki pengetahuan dasar tentang class dan pewarisan di php. Anda juga memiliki pemahaman tentang magic method di php. Magic method karena overloading di php bisa di implmentasikan dengan menggunakan magic method. Overriding        Arti dasar dari overriding di OOP sama dengan arti kata sebenarnya. Dalam arti kata sebenarnya dari overriding adalah menggantikan perilaku orang tua yang sama pada anak. Ini sama dengan override method di OOP. Dalam arti OOP, override adalah mengganti method class induk di class anak. Atau dengan method kata kunci sederhana yang me

Contoh Perhitungan Algoritma Learning Vector Quantization

Melanjutkan tulisan saya tentang algoritma Learning Vector Quantization yang lalu, kali ini saya akan melanjutkan dengan contoh perhitungan manual. Berikut ini contoh data yang akan kita hitung. No X1 X2 X3 X4 target 1 0 1 1 0 0 2 0 0 1 1 1 3 1 1 1 1 0 4 1 0 0 1 1 pada contoh di atas, saya menggunakan 4 data sebagai data training beserta target yang bertujuan untuk mendapatkan bobot yang akan digunakan pada proses klasifikasi. Bobot awal adalah { 1, 1, 1, 0} dan { 1, 0, 1, 1} dengan learning rate 0,05 dengan fungsi pembelajaran = 0,1. Pelatihan Iterasi ke 1 1. Data ke 1 { 0, 1, 1, 0} dengan target 0, bobot = {{ 1, 1, 1, 0},{ 1, 0, 1, 1}}      - menghitung bobot untuk masing masing output :          kelas 0 = sqrt(((0-1)^2)+((1-1)^2)+((1-1)^2)+((0-0)^2)) = 1         kelas 1 = sqrt(((0-1)^2)+((1-0)^2)+((1-