Symfony - Konsep Lanjutan
Di bab ini, kita akan mempelajari beberapa konsep lanjutan dalam framework Symfony.
Cache HTTP
Caching dalam aplikasi web meningkatkan kinerja. Misalnya, produk panas dalam aplikasi web keranjang belanja dapat disimpan dalam cache untuk waktu yang terbatas, sehingga dapat disajikan kepada pelanggan dengan cepat tanpa masuk ke database. Berikut adalah beberapa komponen dasar Cache.
Item Cache
Item Cache adalah satu unit informasi yang disimpan sebagai pasangan kunci / nilai. Itukey harus berupa string dan valuedapat berupa objek PHP apa saja. Objek PHP disimpan sebagai string dengan serialisasi dan diubah kembali menjadi objek saat membaca item.
Adaptor Cache
Adaptor Cache adalah mekanisme sebenarnya untuk menyimpan item di toko. Penyimpanan dapat berupa memori, sistem file, database, redis, dll. Komponen cache menyediakan fileAdapterInterfacemelalui mana adaptor dapat menyimpan item cache di penyimpanan back-end. Ada banyak adaptor cache bawaan yang tersedia. Beberapa di antaranya adalah sebagai berikut -
Adaptor Cache Array - Item cache disimpan dalam array PHP.
Filesystem Cache adapter - Item cache disimpan dalam file.
PHP Files Cache Adapter - Item cache disimpan sebagai file php.
Adaptor Cache APCu - Item cache disimpan dalam memori bersama menggunakan ekstensi PHP APCu.
Redis Cache Adapter - Item cache disimpan di server Redis.
Adaptor Cache DBAL PDO dan Doctrine - Item cache disimpan dalam database.
Chain Cache Adapter - Menggabungkan beberapa adaptor cache untuk tujuan replikasi.
Proxy Cache Adapter - Item cache disimpan menggunakan adaptor pihak ketiga, yang mengimplementasikan CacheItemPoolInterface.
Cache Pool
Cache Pool adalah repositori logis dari item cache. Kumpulan cache diimplementasikan oleh adaptor cache.
Aplikasi Sederhana
Mari kita buat aplikasi sederhana untuk memahami konsep cache.
Step 1 - Buat aplikasi baru, cache-example.
cd /path/to/app
mkdir cache-example
cd cache-example
Step 2 - Instal komponen cache.
composer require symfony/cache
Step 3 - Buat adaptor sistem file.
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
Step 4 - Buat item cache menggunakan getItem dan setmetode adaptor. getItem mengambil item cache menggunakan kuncinya. jika kuncinya tidak ada, itu membuat item baru. metode set menyimpan data aktual.
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']);
$cache->save($usercache);
Step 5 - Akses item cache menggunakan getItem, isHit dan getmetode. isHit menginformasikan ketersediaan item cache dan metode get menyediakan data aktual.
$userCache = $cache->getItem('item.users');
if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
Step 6 - Hapus item cache menggunakan deleteItem metode.
$cache->deleteItem('item.users');
Daftar kode lengkapnya adalah sebagai berikut.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']);
$cache->save($usercache);
$userCache = $cache->getItem('item.users');
if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
$cache->deleteItem('item.users');
?>
Hasil
array(2) {
[0]=>
string(3) "jon"
[1]=>
string(5) "peter"
}
Debug
Debugging adalah salah satu aktivitas yang paling sering dilakukan saat mengembangkan aplikasi. Symfony menyediakan komponen terpisah untuk memudahkan proses debugging. Kita dapat mengaktifkan alat debugging Symfony hanya dengan memanggilenable metode kelas Debug.
use Symfony\Component\Debug\Debug
Debug::enable()
Symfony menyediakan dua kelas, ErrorHandler dan ExceptionHandleruntuk tujuan debugging. Sementara ErrorHandler menangkap kesalahan PHP dan mengubahnya menjadi pengecualian, ErrorException atau FatalErrorException, ExceptionHandler menangkap pengecualian PHP yang tidak tertangkap dan mengubahnya menjadi respons PHP yang berguna. ErrorHandler dan ExceptionHandler dinonaktifkan secara default. Kita bisa mengaktifkannya dengan menggunakan metode register.
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
ErrorHandler::register();
ExceptionHandler::register();
Dalam aplikasi web Symfony, file debug environmentdisediakan oleh DebugBundle. Daftarkan bundel di AppKernel'sregisterBundles metode untuk mengaktifkannya.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
}
Profiler
Pengembangan aplikasi membutuhkan alat pembuatan profil kelas dunia. Alat pembuatan profil mengumpulkan semua informasi run-time tentang aplikasi seperti waktu eksekusi, waktu eksekusi modul individu, waktu yang dibutuhkan oleh aktivitas database, penggunaan memori, dll. Aplikasi web memerlukan lebih banyak informasi seperti waktu permintaan, waktu yang dibutuhkan untuk membuat tanggapan, dll. selain metrik di atas.
Symfony mengaktifkan semua informasi semacam itu dalam aplikasi web secara default. Symfony menyediakan bundel terpisah untuk pembuatan profil web yang disebutWebProfilerBundle. Paket profiler web dapat diaktifkan dalam aplikasi web dengan mendaftarkan bundel tersebut di metode registerBundles AppKernel.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
}
Komponen profil web dapat dikonfigurasi di bawah web_profile section dari file konfigurasi aplikasi, app/config/config.xml
web_profiler:
toolbar: false
position: bottom
Aplikasi Symfony menampilkan data yang diprofilkan di bagian bawah halaman sebagai bagian yang berbeda.
Symfony juga menyediakan cara mudah untuk menambahkan detail kustom tentang halaman di data profil menggunakan DataCollectorInterface interfacedan ranting template. Singkatnya, Symfony memungkinkan pengembang web membuat aplikasi kelas dunia dengan menyediakan kerangka kerja profil yang bagus dengan relatif mudah.
Keamanan
Seperti yang telah dibahas sebelumnya, Symfony menyediakan kerangka kerja keamanan yang kuat melalui komponen keamanannya. Komponen keamanan dibagi menjadi empat sub-komponen sebagai berikut.
- symfony / security-core - Fungsionalitas keamanan inti.
- symfony / security-http - Fitur keamanan terintegrasi dalam protokol HTTP.
- symfony / security-csrf - Perlindungan terhadap pemalsuan permintaan lintas situs dalam aplikasi web.
- symfony / security-acl - Kerangka kerja keamanan berbasis daftar kontrol akses lanjutan.
Otentikasi dan Otorisasi Sederhana
Mari kita pelajari konsep otentikasi dan otorisasi menggunakan aplikasi demo sederhana.
Step 1 - Buat aplikasi web baru securitydemo menggunakan perintah berikut.
symfony new securitydemo
Step 2- Aktifkan fitur keamanan dalam aplikasi menggunakan file konfigurasi keamanan. Konfigurasi terkait keamanan ditempatkan dalam file terpisah,security.yml. Konfigurasi defaultnya adalah sebagai berikut.
security:
providers:
in_memory:
memory: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
#http_basic: ~
#form_login: ~
Konfigurasi default memungkinkan penyedia keamanan berbasis memori dan akses anonim ke semua halaman. Bagian firewall mengecualikan file yang cocok dengan pola,^/(_(profiler|wdt)|css|images|js)/dari kerangka keamanan. Pola default mencakup stylesheet, gambar, dan JavaScripts (ditambah alat pengembang seperti profiler).
Step 3 - Aktifkan sistem otentikasi keamanan berbasis HTTP dengan menambahkan opsi http_basic di bagian utama sebagai berikut.
security:
# ...
firewalls:
# ...
main:
anonymous: ~
http_basic: ~
#form_login: ~
Step 4- Tambahkan beberapa pengguna di bagian penyedia memori. Tambahkan juga peran untuk pengguna.
security:
providers:
in_memory:
memory:
users:
myuser:
password: user
roles: 'ROLE_USER'
myadmin:
password: admin
roles: 'ROLE_ADMIN'
Kami telah menambahkan dua pengguna, pengguna dalam peran ROLE_USER dan admin dalam peran ROLE_ADMIN.
Step 5- Tambahkan encoder untuk mendapatkan detail lengkap dari pengguna yang login saat ini. Tujuan pembuat enkode adalah untuk mendapatkan detail lengkap tentang objek pengguna saat ini dari permintaan web.
security:
# ...
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
# ...
Symfony menyediakan antarmuka, UserInterface untuk mendapatkan detail pengguna seperti nama pengguna, peran, kata sandi, dll. Kita perlu mengimplementasikan antarmuka untuk kebutuhan kita dan mengkonfigurasinya di bagian encoder.
Misalnya, mari kita pertimbangkan bahwa detail pengguna ada di database. Kemudian, kita perlu membuat kelas User baru dan mengimplementasikan metode UserInterface untuk mendapatkan detail pengguna dari database. Setelah data tersedia, maka sistem keamanan menggunakannya untuk mengizinkan / menolak pengguna. Symfony menyediakan implementasi Pengguna default untuk penyedia Memori. Algoritma digunakan untuk mendekripsi kata sandi pengguna.
Step 6 - Enkripsi kata sandi pengguna menggunakan bcryptalgoritma dan letakkan di file konfigurasi. Sejak kami dulubcryptalgoritma, objek Pengguna mencoba mendekripsi kata sandi yang ditentukan dalam file konfigurasi dan kemudian mencoba mencocokkan dengan kata sandi yang dimasukkan oleh pengguna. Aplikasi konsol Symfony menyediakan perintah sederhana untuk mengenkripsi kata sandi.
php bin/console security:encode-password admin
Symfony Password Encoder Utility
================================
------------------ -----------------------------------
Key Value
------------------ ------------------------------------
Encoder used Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder
Encoded password
$2y$12$0Hy6/.MNxWdFcCRDdstHU.hT5j3Mg1tqBunMLIUYkz6..IucpaPNO
------------------ ------------------------------------
! [NOTE] Bcrypt encoder used: the encoder generated its own built-in salt.
[OK] Password encoding succeeded
Step 7 - Gunakan perintah untuk membuat kata sandi terenkripsi dan memperbaruinya di file konfigurasi.
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
in_memory:
memory:
users:
user:
password: $2y$13$WsGWNufreEnVK1InBXL2cO/U7WftvfNvH
Vb/IJBH6JiYoDwVN4zoi
roles: 'ROLE_USER'
admin:
password: $2y$13$jQNdIeoNV1BKVbpnBuhKRuOL01NeMK
F7nEqEi/Mqlzgts0njK3toy
roles: 'ROLE_ADMIN'
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
firewalls:
# disables authentication for assets and the profiler,
# adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# activate different ways to authenticate
# http://symfony.com/doc/current/security.html#a-co
nfiguring-howyour-users-will-authenticate
http_basic: ~
# http://symfony.com/doc/current/cookbook/security/
form_login_setup.html
#form_login: ~
Step 8- Sekarang, terapkan keamanan ke beberapa bagian aplikasi. Misalnya, batasi bagian admin untuk pengguna yang berperan, ROLE_ADMIN.
security:
# ...
firewalls:
# ...
default:
# ...
access_control:
# require ROLE_ADMIN for /admin*
- { path: ^/admin, roles: 'ROLE_ADMIN' }
Step 9 - Tambahkan halaman admin di DefaultController sebagai berikut.
/**
* @Route("/admin")
*/
public function adminLandingAction() {
return new Response('<html><body>This is admin section.</body></html>');
}
Step 10- Terakhir, akses halaman admin untuk memeriksa konfigurasi keamanan di browser. Browser akan meminta nama pengguna dan kata sandi dan hanya mengizinkan pengguna yang dikonfigurasi.
Hasil
Alur Kerja
Alur kerja adalah konsep lanjutan yang digunakan di banyak aplikasi perusahaan. Dalam aplikasi e-niaga, proses pengiriman produk adalah alur kerja. Produk pertama kali ditagih (pembuatan pesanan), diperoleh dari toko dan dikemas (pengemasan / siap dikirim), dan dikirim ke pengguna. Jika ada masalah, produk dikembalikan dari pengguna dan pesanan dikembalikan. Urutan aliran tindakan sangat penting. Misalnya, kami tidak dapat mengirimkan produk tanpa penagihan.
Komponen Symfony menyediakan cara berorientasi objek untuk mendefinisikan dan mengelola alur kerja. Setiap langkah dalam suatu proses disebutplace dan tindakan yang diperlukan untuk berpindah dari satu tempat ke tempat lain disebut transition. Kumpulan tempat dan transisi untuk membuat alur kerja disebut aWorkflow definition.
Mari kita pahami konsep alur kerja dengan membuat aplikasi sederhana untuk manajemen cuti.
Step 1 - Buat aplikasi baru, workflow-example.
cd /path/to/dev
mkdir workflow-example
cd workflow-example
composer require symfony/workflow
Step 2 - Buat kelas baru, Leave memiliki applied_by, leave_on dan status atribut.
class Leave {
public $applied_by;
public $leave_on;
public $status;
}
Di sini, apply_by mengacu pada karyawan yang ingin cuti. leave_on mengacu pada tanggal cuti. status mengacu pada status cuti.
Step 3 - Manajemen cuti memiliki empat tempat, diterapkan, dalam proses, dan disetujui / ditolak.
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
$builder = new DefinitionBuilder();
$builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
Di sini, kami telah membuat definisi baru menggunakan DefinitionBuilder dan menambahkan tempat menggunakan addPlaces metode.
Step 4 - Tentukan tindakan yang diperlukan untuk berpindah dari satu tempat ke tempat lain.
$builder->addTransition(new Transition('to_process', 'applied', 'in_process'));
$builder->addTransition(new Transition('approve', 'in_process', 'approved'));
$builder->addTransition(new Transition('reject', 'in_process', 'rejected'));
Di sini, kami memiliki tiga transisi, to_process, approve dan reject. transisi to_process menerima aplikasi cuti dan memindahkan tempat dari diterapkan ke in_process. menyetujui transisi menyetujui aplikasi cuti dan memindahkan tempat untuk disetujui. Demikian pula, menolak transisi menolak aplikasi cuti dan memindahkan tempat ke ditolak. Kami telah membuat semua transisi menggunakan metode addTransition.
Step 5 - Buat definisi menggunakan metode build.
$definition = $builder->build();
Step 6 - Secara opsional, definisi dapat dibuang sebagai format titik graphviz, yang dapat dikonversi ke file gambar untuk tujuan referensi.
$dumper = new GraphvizDumper();
echo $dumper->dump($definition);
Step 7 - Membuat marking store, yang digunakan untuk menyimpan tempat / status objek saat ini.
$marking = new SingleStateMarkingStore('status');
Di sini, kami telah menggunakan SingleStateMarkingStorekelas untuk membuat tanda dan menandai status saat ini menjadi properti status objek. Dalam contoh kita, objeknya adalah objek Tinggalkan.
Step 8 - Buat alur kerja menggunakan definisi dan penandaan.
$leaveWorkflow = new Workflow($definition, $marking);
Di sini, kami telah menggunakan Workflow kelas untuk membuat alur kerja.
Step 9 - Tambahkan alur kerja ke dalam registri kerangka alur kerja menggunakan Registry kelas.
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
Step 10 - Terakhir, gunakan alur kerja untuk menemukan apakah transisi tertentu diterapkan menggunakan can metode dan jika demikian, applytransisi menggunakan metode terapkan. Saat transisi diterapkan, status objek berpindah dari satu tempat ke tempat lain.
$workflow = $registry->get($leave);
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n";
$workflow->apply($leave, 'to_process');
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo $leave->status . "\r\n";
$workflow->apply($leave, 'approve');
echo $leave->status . "\r\n";
Pengodean lengkapnya adalah sebagai berikut -
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
class Leave {
public $applied_by;
public $leave_on;
public $status;
}
$builder = new DefinitionBuilder();
$builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
$builder->addTransition(new Transition('to_process', 'applied', 'in_process'));
$builder->addTransition(new Transition('approve', 'in_process', 'approved'));
$builder->addTransition(new Transition('reject', 'in_process', 'rejected'));
$definition = $builder->build();
// $dumper = new GraphvizDumper();
// echo $dumper->dump($definition);
$marking = new SingleStateMarkingStore('status');
$leaveWorkflow = new Workflow($definition, $marking);
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
$leave = new Leave();
$leave->applied_by = "Jon";
$leave->leave_on = "1998-12-12";
$leave->status = 'applied';
$workflow = $registry->get($leave);
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n";
$workflow->apply($leave, 'to_process');
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo $leave->status . "\r\n";
$workflow->apply($leave, 'approve');
echo $leave->status . "\r\n";
?>
Hasil
Can we approve the leave now?
Can we approve the start process now? 1
Can we approve the leave now? 1
in_process
approved