Learn
Pelajari Tentang Flight
Flight adalah framework PHP yang cepat, sederhana, dan dapat diperluas. Ini cukup serbaguna dan dapat digunakan untuk membangun berbagai jenis aplikasi web. Ini dibangun dengan kesederhanaan dalam pikiran dan ditulis dengan cara yang mudah dipahami dan digunakan.
Konsep Penting dalam Framework
Mengapa Menggunakan Framework?
Berikut adalah artikel singkat tentang mengapa Anda harus menggunakan framework. Ini adalah ide yang baik untuk memahami manfaat menggunakan framework sebelum Anda mulai menggunakannya.
Selain itu, tutorial yang sangat baik telah dibuat oleh @lubiana. Meskipun tidak membahas secara mendalam tentang Flight secara spesifik, petunjuk ini akan membantu Anda memahami beberapa konsep utama seputar framework dan mengapa mereka bermanfaat untuk digunakan. Anda dapat menemukan tutorial tersebut di sini.
Flight Dibandingkan dengan Framework Lain
Jika Anda bermigrasi dari framework lain seperti Laravel, Slim, Fat-Free, atau Symfony ke Flight, halaman ini akan membantu Anda memahami perbedaan antara keduanya.
Topik Inti
Autoloading
Pelajari cara meng-autoload kelas Anda sendiri dalam aplikasi Anda.
Routing
Pelajari cara mengelola rute untuk aplikasi web Anda. Ini juga termasuk pengelompokan rute, parameter rute, dan middleware.
Middleware
Pelajari cara menggunakan middleware untuk memfilter permintaan dan respon dalam aplikasi Anda.
Requests
Pelajari cara menangani permintaan dan respon dalam aplikasi Anda.
Responses
Pelajari cara mengirim respon kepada pengguna Anda.
HTML Templates
Pelajari cara menggunakan mesin tampilan bawaan untuk merender template HTML Anda.
Keamanan
Pelajari cara mengamankan aplikasi Anda dari ancaman keamanan yang umum.
Konfigurasi
Pelajari cara mengonfigurasi framework untuk aplikasi Anda.
Memperluas Flight
Pelajari cara memperluas framework dengan menambahkan metode dan kelas Anda sendiri.
Event dan Penyaringan
Pelajari cara menggunakan sistem event untuk menambahkan hook ke metode Anda dan metode internal framework.
Kontainer Injeksi Ketergantungan
Pelajari cara menggunakan kontainer injeksi ketergantungan (DIC) untuk mengelola ketergantungan aplikasi Anda.
API Framework
Pelajari tentang metode inti dari framework.
Migrasi ke v3
Kompatibilitas mundur sebagian besar telah dipertahankan, tetapi ada beberapa perubahan yang harus Anda ketahui saat bermigrasi dari v2 ke v3.
Memecahkan Masalah
Ada beberapa masalah umum yang mungkin Anda temui saat menggunakan Flight. Halaman ini akan membantu Anda memecahkan masalah tersebut.
Learn/flight_vs_laravel
Flight vs Laravel
Apa itu Laravel?
Laravel adalah framework yang memiliki fitur lengkap yang dilengkapi dengan segala hal menarik dan ekosistem yang berfokus pada pengembang, tetapi dengan biaya dalam hal kinerja dan kompleksitas. Tujuan Laravel adalah agar pengembang memiliki tingkat produktivitas tertinggi dan untuk memudahkan tugas-tugas umum. Laravel adalah pilihan yang baik bagi pengembang yang mencari untuk membangun aplikasi web berfitur lengkap untuk perusahaan. Itu datang dengan beberapa pertukaran, terutama dalam hal kinerja dan kompleksitas. Mempelajari dasar-dasar Laravel bisa jadi mudah, tetapi menguasai framework ini bisa memakan waktu.
Ada juga banyak modul Laravel sehingga pengembang sering merasa bahwa satu-satunya cara untuk menyelesaikan masalah adalah melalui modul-modul ini, padahal sebenarnya Anda bisa saja menggunakan perpustakaan lain atau menulis kode Anda sendiri.
Kelebihan dibandingkan Flight
- Laravel memiliki ekosistem yang besar dari pengembang dan modul yang dapat digunakan untuk memecahkan masalah umum.
- Laravel memiliki ORM berfitur lengkap yang dapat digunakan untuk berinteraksi dengan basis data Anda.
- Laravel memiliki jumlah dokumentasi dan tutorial yang luar biasa yang dapat digunakan untuk mempelajari framework ini.
- Laravel memiliki sistem autentikasi bawaan yang dapat digunakan untuk mengamankan aplikasi Anda.
- Laravel memiliki podcast, konferensi, pertemuan, video, dan sumber daya lainnya yang dapat digunakan untuk mempelajari framework ini.
- Laravel ditujukan untuk pengembang berpengalaman yang mencari untuk membangun aplikasi web berfitur lengkap untuk perusahaan.
Kekurangan dibandingkan Flight
- Laravel memiliki lebih banyak hal yang terjadi di balik layar dibandingkan dengan Flight. Ini datang dengan biaya yang dramatis dalam hal kinerja. Lihat benchmark TechEmpower untuk informasi lebih lanjut.
- Flight ditujukan untuk pengembang yang ingin membangun aplikasi web yang ringan, cepat, dan mudah digunakan.
- Flight ditujukan untuk kesederhanaan dan kemudahan penggunaan.
- Salah satu fitur inti Flight adalah bahwa ia berusaha sebaik mungkin untuk menjaga kompatibilitas ke belakang. Laravel menyebabkan banyak frustrasi antara versi besar.
- Flight ditujukan untuk pengembang yang menjelajahi dunia framework untuk pertama kalinya.
- Flight tidak memiliki ketergantungan, sedangkan Laravel memiliki jumlah ketergantungan yang sangat banyak
- Flight juga dapat melakukan aplikasi tingkat perusahaan, tetapi tidak memiliki sebanyak kode boilerplate seperti yang dimiliki Laravel. Itu juga akan memerlukan lebih banyak disiplin dari pihak pengembang untuk menjaga segala sesuatunya terorganisir dan terstruktur dengan baik.
- Flight memberi pengembang lebih banyak kontrol atas aplikasinya, sedangkan Laravel memiliki banyak keajaiban di balik layar yang bisa membuat frustrasi.
Learn/migrating_to_v3
Migrasi ke v3
Kompatibilitas ke belakang sebagian besar telah dipertahankan, tetapi ada beberapa perubahan yang harus Anda perhatikan saat migrasi dari v2 ke v3.
Perilaku Buffering Output (3.5.0)
Buffering output adalah proses di mana output yang dihasilkan oleh skrip PHP disimpan dalam buffer (internal di PHP) sebelum dikirim ke klien. Ini memungkinkan Anda untuk memodifikasi output sebelum dikirim ke klien.
Dalam aplikasi MVC, Controller adalah "pengelola" dan mengatur apa yang dilakukan tampilan. Memiliki output yang dihasilkan di luar controller (atau dalam kasus Flight kadang-kadang fungsi anonim) merusak pola MVC. Perubahan ini bertujuan untuk lebih selaras dengan pola MVC dan untuk membuat framework lebih dapat diprediksi dan lebih mudah digunakan.
Di v2, buffering output ditangani sedemikian rupa sehingga tidak secara konsisten menutup buffer output sendiri dan ini membuat unit testing dan streaming menjadi lebih sulit. Untuk sebagian besar pengguna, perubahan ini mungkin tidak benar-benar memengaruhi Anda. Namun jika Anda mencetak konten di luar callable dan controller (misalnya dalam hook), Anda kemungkinan akan menghadapi masalah. Mencetak konten dalam hook, dan sebelum framework benar-benar mengeksekusi mungkin berfungsi di masa lalu, tetapi tidak akan berfungsi ke depan.
Di mana Anda mungkin mengalami masalah
// index.php
require 'vendor/autoload.php';
// hanya contoh
define('START_TIME', microtime(true));
function hello() {
echo 'Hello World';
}
Flight::map('hello', 'hello');
Flight::after('hello', function(){
// ini sebenarnya baik-baik saja
echo '<p>Frasa Hello World ini dibawakan kepada Anda oleh huruf "H"</p>';
});
Flight::before('start', function(){
// hal-hal seperti ini akan menyebabkan kesalahan
echo '<html><head><title>Halaman Saya</title></head><body>';
});
Flight::route('/', function(){
// ini sebenarnya baik-baik saja
echo 'Hello World';
// Ini juga seharusnya baik-baik saja
Flight::hello();
});
Flight::after('start', function(){
// ini akan menyebabkan kesalahan
echo '<div>Halaman Anda dimuat dalam '.(microtime(true) - START_TIME).' detik</div></body></html>';
});
Mengaktifkan Perilaku Rendering v2
Apakah Anda masih bisa menjaga kode lama Anda seperti semula tanpa melakukan penulisan ulang untuk membuatnya berfungsi dengan v3? Ya, Anda bisa! Anda dapat mengaktifkan
perilaku rendering v2 dengan mengatur opsi konfigurasi flight.v2.output_buffering
menjadi true
. Ini akan memungkinkan Anda untuk terus menggunakan
perilaku rendering lama, tetapi disarankan untuk memperbaikinya ke depan. Di v4 dari framework, ini akan dihapus.
// index.php
require 'vendor/autoload.php';
Flight::set('flight.v2.output_buffering', true);
Flight::before('start', function(){
// Sekarang ini akan baik-baik saja
echo '<html><head><title>Halaman Saya</title></head><body>';
});
// lebih banyak kode
Perubahan Dispatcher (3.7.0)
Jika Anda langsung memanggil metode statis untuk Dispatcher
seperti Dispatcher::invokeMethod()
, Dispatcher::execute()
, dll.
Anda perlu memperbarui kode Anda agar tidak langsung memanggil metode ini. Dispatcher
telah diubah menjadi lebih berorientasi objek sehingga
Container Penyuntikan Ketergantungan dapat digunakan dengan cara yang lebih mudah. Jika Anda perlu memanggil metode mirip seperti yang dilakukan Dispatcher, Anda
dapat menggunakan sesuatu seperti $result = $class->$method(...$params);
atau call_user_func_array()
sebagai gantinya.
Perubahan halt()
stop()
redirect()
dan error()
(3.10.0)
Perilaku default sebelum 3.10.0 adalah untuk menghapus baik header maupun body respons. Ini diubah hanya untuk menghapus body respons.
Jika Anda perlu menghapus header juga, Anda bisa menggunakan Flight::response()->clear()
.
Learn/configuration
Konfigurasi
Anda dapat menyesuaikan perilaku tertentu dari Flight dengan menetapkan nilai konfigurasi melalui metode set
.
Flight::set('flight.log_errors', true);
Pengaturan Konfigurasi Tersedia
Berikut adalah daftar semua pengaturan konfigurasi yang tersedia:
- flight.base_url
?string
- Gantilah URL dasar dari permintaan. (default: null) - flight.case_sensitive
bool
- Pencocokan sensitif terhadap huruf untuk URL. (default: false) - flight.handle_errors
bool
- Izinkan Flight menangani semua kesalahan secara internal. (default: true) - flight.log_errors
bool
- Catat kesalahan ke file log kesalahan server web. (default: false) - flight.views.path
string
- Direktori yang berisi file template tampilan. (default: ./views) - flight.views.extension
string
- Ekstensi file template tampilan. (default: .php) - flight.content_length
bool
- Atur headerContent-Length
. (default: true) - flight.v2.output_buffering
bool
- Gunakan buffering output tradisional. Lihat migrasi ke v3. (default: false)
Konfigurasi Loader
Selain itu, ada pengaturan konfigurasi lain untuk loader. Ini akan memungkinkan Anda
untuk memuat kelas secara otomatis dengan _
dalam nama kelas.
// Aktifkan pemuatan kelas dengan garis bawah
// Defaultnya adalah true
Loader::$v2ClassLoading = false;
Variabel
Flight memungkinkan Anda untuk menyimpan variabel sehingga dapat digunakan di mana saja dalam aplikasi Anda.
// Simpan variabel Anda
Flight::set('id', 123);
// Di tempat lain dalam aplikasi Anda
$id = Flight::get('id');
Untuk melihat apakah sebuah variabel telah disetel, Anda dapat melakukan:
if (Flight::has('id')) {
// Lakukan sesuatu
}
Anda dapat menghapus variabel dengan melakukan:
// Menghapus variabel id
Flight::clear('id');
// Menghapus semua variabel
Flight::clear();
Flight juga menggunakan variabel untuk tujuan konfigurasi.
Flight::set('flight.log_errors', true);
Penanganan Kesalahan
Kesalahan dan Pengecualian
Semua kesalahan dan pengecualian ditangkap oleh Flight dan diteruskan ke metode error
.
Perilaku default adalah mengirimkan respons HTTP 500 Internal Server Error
dengan beberapa informasi kesalahan.
Anda dapat mengganti perilaku ini sesuai kebutuhan Anda:
Flight::map('error', function (Throwable $error) {
// Tangani kesalahan
echo $error->getTraceAsString();
});
Secara default kesalahan tidak dicatat ke server web. Anda dapat mengaktifkan ini dengan mengubah konfigurasi:
Flight::set('flight.log_errors', true);
Tidak Ditemukan
Ketika sebuah URL tidak dapat ditemukan, Flight memanggil metode notFound
. Perilaku default
adalah mengirimkan respons HTTP 404 Not Found
dengan pesan sederhana.
Anda dapat mengganti perilaku ini sesuai kebutuhan Anda:
Flight::map('notFound', function () {
// Tangani tidak ditemukan
});
Learn/security
Keamanan
Keamanan adalah hal yang sangat penting ketika datang ke aplikasi web. Anda ingin memastikan bahwa aplikasi Anda aman dan bahwa data pengguna Anda berada dalam keadaan aman. Flight menyediakan sejumlah fitur untuk membantu Anda mengamankan aplikasi web Anda.
Header
Header HTTP adalah salah satu cara termudah untuk mengamankan aplikasi web Anda. Anda dapat menggunakan header untuk mencegah clickjacking, XSS, dan serangan lainnya. Ada beberapa cara yang dapat Anda lakukan untuk menambahkan header ini ke aplikasi Anda.
Dua situs web hebat untuk memeriksa keamanan header Anda adalah securityheaders.com dan observatory.mozilla.org.
Tambahkan Secara Manual
Anda dapat menambahkan header ini secara manual dengan menggunakan metode header
pada objek Flight\Response
.
// Setel header X-Frame-Options untuk mencegah clickjacking
Flight::response()->header('X-Frame-Options', 'SAMEORIGIN');
// Setel header Content-Security-Policy untuk mencegah XSS
// Catatan: header ini dapat menjadi sangat kompleks, jadi Anda ingin
// berkonsultasi dengan contoh di internet untuk aplikasi Anda
Flight::response()->header("Content-Security-Policy", "default-src 'self'");
// Setel header X-XSS-Protection untuk mencegah XSS
Flight::response()->header('X-XSS-Protection', '1; mode=block');
// Setel header X-Content-Type-Options untuk mencegah MIME sniffing
Flight::response()->header('X-Content-Type-Options', 'nosniff');
// Setel header Referrer-Policy untuk mengontrol seberapa banyak informasi referrer yang dikirim
Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade');
// Setel header Strict-Transport-Security untuk memaksa HTTPS
Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
// Setel header Permissions-Policy untuk mengontrol fitur dan API mana yang dapat digunakan
Flight::response()->header('Permissions-Policy', 'geolocation=()');
Header ini dapat ditambahkan di bagian atas file bootstrap.php
atau index.php
Anda.
Tambahkan sebagai Filter
Anda juga dapat menambahkannya dalam filter/hook seperti berikut:
// Tambahkan header dalam filter
Flight::before('start', function() {
Flight::response()->header('X-Frame-Options', 'SAMEORIGIN');
Flight::response()->header("Content-Security-Policy", "default-src 'self'");
Flight::response()->header('X-XSS-Protection', '1; mode=block');
Flight::response()->header('X-Content-Type-Options', 'nosniff');
Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade');
Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
Flight::response()->header('Permissions-Policy', 'geolocation=()');
});
Tambahkan sebagai Middleware
Anda juga dapat menambahkannya sebagai kelas middleware. Ini adalah cara yang baik untuk menjaga kode Anda tetap bersih dan terorganisir.
// app/middleware/SecurityHeadersMiddleware.php
namespace app\middleware;
class SecurityHeadersMiddleware
{
public function before(array $params): void
{
Flight::response()->header('X-Frame-Options', 'SAMEORIGIN');
Flight::response()->header("Content-Security-Policy", "default-src 'self'");
Flight::response()->header('X-XSS-Protection', '1; mode=block');
Flight::response()->header('X-Content-Type-Options', 'nosniff');
Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade');
Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
Flight::response()->header('Permissions-Policy', 'geolocation=()');
}
}
// index.php atau di mana pun Anda memiliki rute Anda
// FYI, grup string kosong ini bertindak sebagai middleware global untuk
// semua rute. Tentu saja, Anda bisa melakukan hal yang sama dan hanya menambahkan
// ini hanya pada rute tertentu.
Flight::group('', function(Router $router) {
$router->get('/users', [ 'UserController', 'getUsers' ]);
// lebih banyak rute
}, [ new SecurityHeadersMiddleware() ]);
Cross Site Request Forgery (CSRF)
Cross Site Request Forgery (CSRF) adalah jenis serangan di mana situs web jahat dapat membuat browser pengguna mengirim permintaan ke situs web Anda. Ini dapat digunakan untuk melakukan tindakan di situs web Anda tanpa sepengetahuan pengguna. Flight tidak menyediakan mekanisme perlindungan CSRF bawaan, tetapi Anda dapat dengan mudah mengimplementasikan sendiri dengan menggunakan middleware.
Pengaturan
Pertama, Anda perlu menghasilkan token CSRF dan menyimpannya di sesi pengguna. Anda kemudian dapat menggunakan token ini di formulir Anda dan memeriksa saat formulir dikirimkan.
// Hasilkan token CSRF dan simpan di sesi pengguna
// (mengasumsikan Anda telah membuat objek sesi dan melampirkannya ke Flight)
// lihat dokumentasi sesi untuk informasi lebih lanjut
Flight::register('session', \Ghostff\Session\Session::class);
// Anda hanya perlu menghasilkan satu token per sesi (agar berfungsi
// di beberapa tab dan permintaan untuk pengguna yang sama)
if(Flight::session()->get('csrf_token') === null) {
Flight::session()->set('csrf_token', bin2hex(random_bytes(32)) );
}
<!-- Gunakan token CSRF di formulir Anda -->
<form method="post">
<input type="hidden" name="csrf_token" value="<?= Flight::session()->get('csrf_token') ?>">
<!-- field formulir lainnya -->
</form>
Menggunakan Latte
Anda juga dapat mengatur fungsi khusus untuk menampilkan token CSRF di template Latte Anda.
// Atur fungsi khusus untuk menampilkan token CSRF
// Catatan: Tampilan telah dikonfigurasi dengan Latte sebagai mesin tampilan
Flight::view()->addFunction('csrf', function() {
$csrfToken = Flight::session()->get('csrf_token');
return new \Latte\Runtime\Html('<input type="hidden" name="csrf_token" value="' . $csrfToken . '">');
});
Dan sekarang di template Latte Anda, Anda dapat menggunakan fungsi csrf()
untuk menampilkan token CSRF.
<form method="post">
{csrf()}
<!-- field formulir lainnya -->
</form>
Singkat dan sederhana, bukan?
Periksa Token CSRF
Anda dapat memeriksa token CSRF menggunakan filter acara:
// Middleware ini memeriksa apakah permintaan adalah permintaan POST dan jika ya, memeriksa apakah token CSRF valid
Flight::before('start', function() {
if(Flight::request()->method == 'POST') {
// ambil token csrf dari nilai formulir
$token = Flight::request()->data->csrf_token;
if($token !== Flight::session()->get('csrf_token')) {
Flight::halt(403, 'Token CSRF tidak valid');
// atau untuk respon JSON
Flight::jsonHalt(['error' => 'Token CSRF tidak valid'], 403);
}
}
});
Atau Anda dapat menggunakan kelas middleware:
// app/middleware/CsrfMiddleware.php
namespace app\middleware;
class CsrfMiddleware
{
public function before(array $params): void
{
if(Flight::request()->method == 'POST') {
$token = Flight::request()->data->csrf_token;
if($token !== Flight::session()->get('csrf_token')) {
Flight::halt(403, 'Token CSRF tidak valid');
}
}
}
}
// index.php atau di mana pun Anda memiliki rute
Flight::group('', function(Router $router) {
$router->get('/users', [ 'UserController', 'getUsers' ]);
// lebih banyak rute
}, [ new CsrfMiddleware() ]);
Cross Site Scripting (XSS)
Cross Site Scripting (XSS) adalah jenis serangan di mana situs web jahat dapat menyisipkan kode ke situs web Anda. Sebagian besar peluang ini muncul dari nilai formulir yang akan diisi oleh pengguna akhir Anda. Anda tidak boleh pernah mempercayai output dari pengguna Anda! Selalu anggap semua dari mereka adalah pengacau terbaik di dunia. Mereka dapat menyisipkan JavaScript atau HTML berbahaya ke dalam halaman Anda. Kode ini dapat digunakan untuk mencuri informasi dari pengguna Anda atau melakukan tindakan di situs web Anda. Menggunakan kelas tampilan Flight, Anda dapat dengan mudah melarikan output untuk mencegah serangan XSS.
// Mari kita anggap pengguna cukup cerdas dan mencoba menggunakan ini sebagai nama mereka
$name = '<script>alert("XSS")</script>';
// Ini akan melarikan output
Flight::view()->set('name', $name);
// Ini akan menghasilkan: <script>alert("XSS")</script>
// Jika Anda menggunakan sesuatu seperti Latte yang terdaftar sebagai kelas tampilan Anda, itu juga akan secara otomatis melarikan ini.
Flight::view()->render('template', ['name' => $name]);
SQL Injection
SQL Injection adalah jenis serangan di mana pengguna jahat dapat menyisipkan kode SQL ke dalam database Anda. Ini dapat digunakan untuk mencuri informasi
dari database Anda atau melakukan tindakan di database Anda. Sekali lagi, Anda tidak boleh mempercayai input dari pengguna Anda! Selalu anggap mereka
mencari darah. Anda dapat menggunakan pernyataan yang dipersiapkan dalam objek PDO
Anda untuk mencegah injeksi SQL.
// Mengasumsikan Anda memiliki Flight::db() terdaftar sebagai objek PDO Anda
$statement = Flight::db()->prepare('SELECT * FROM users WHERE username = :username');
$statement->execute([':username' => $username]);
$users = $statement->fetchAll();
// Jika Anda menggunakan kelas PdoWrapper, ini dapat dengan mudah dilakukan dalam satu baris
$users = Flight::db()->fetchAll('SELECT * FROM users WHERE username = :username', [ 'username' => $username ]);
// Anda dapat melakukan hal yang sama dengan objek PDO dengan placeholder ?
$statement = Flight::db()->fetchAll('SELECT * FROM users WHERE username = ?', [ $username ]);
// Hanya janjikan Anda tidak akan PERNAH melakukan sesuatu seperti ini...
$users = Flight::db()->fetchAll("SELECT * FROM users WHERE username = '{$username}' LIMIT 5");
// karena bagaimana jika $username = "' OR 1=1; -- ";
// Setelah kueri dibangun, sepertinya ini
// SELECT * FROM users WHERE username = '' OR 1=1; -- LIMIT 5
// Sepertinya aneh, tetapi itu adalah kueri yang valid yang akan berhasil. Faktanya,
// ini adalah serangan injeksi SQL yang sangat umum yang akan mengembalikan semua pengguna.
CORS
Cross-Origin Resource Sharing (CORS) adalah mekanisme yang memungkinkan banyak sumber daya (misalnya, font, JavaScript, dll.) pada halaman web untuk
diminta dari domain lain di luar domain dari mana sumber daya itu berasal. Flight tidak memiliki fungsi bawaan,
tetapi ini dapat dengan mudah ditangani dengan hook yang dijalankan sebelum metode Flight::start()
dipanggil.
// app/utils/CorsUtil.php
namespace app\utils;
class CorsUtil
{
public function set(array $params): void
{
$request = Flight::request();
$response = Flight::response();
if ($request->getVar('HTTP_ORIGIN') !== '') {
$this->allowOrigins();
$response->header('Access-Control-Allow-Credentials', 'true');
$response->header('Access-Control-Max-Age', '86400');
}
if ($request->method === 'OPTIONS') {
if ($request->getVar('HTTP_ACCESS_CONTROL_REQUEST_METHOD') !== '') {
$response->header(
'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD'
);
}
if ($request->getVar('HTTP_ACCESS_CONTROL_REQUEST_HEADERS') !== '') {
$response->header(
"Access-Control-Allow-Headers",
$request->getVar('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
);
}
$response->status(200);
$response->send();
exit;
}
}
private function allowOrigins(): void
{
// sesuaikan host yang diizinkan di sini.
$allowed = [
'capacitor://localhost',
'ionic://localhost',
'http://localhost',
'http://localhost:4200',
'http://localhost:8080',
'http://localhost:8100',
];
$request = Flight::request();
if (in_array($request->getVar('HTTP_ORIGIN'), $allowed, true) === true) {
$response = Flight::response();
$response->header("Access-Control-Allow-Origin", $request->getVar('HTTP_ORIGIN'));
}
}
}
// index.php atau di mana pun Anda memiliki rute
$CorsUtil = new CorsUtil();
// Ini perlu dijalankan sebelum mulai berjalan.
Flight::before('start', [ $CorsUtil, 'setupCors' ]);
Kesimpulan
Keamanan adalah hal yang sangat penting dan penting untuk memastikan aplikasi web Anda aman. Flight menyediakan sejumlah fitur untuk membantu Anda mengamankan aplikasi web Anda, tetapi penting untuk selalu waspada dan memastikan Anda melakukan semua yang Anda bisa untuk menjaga data pengguna Anda aman. Selalu anggap yang terburuk dan jangan pernah mempercayai input dari pengguna Anda. Selalu melarikan output dan gunakan pernyataan yang dipersiapkan untuk mencegah injeksi SQL. Selalu gunakan middleware untuk melindungi rute Anda dari serangan CSRF dan CORS. Jika Anda melakukan semua hal ini, Anda akan berada di jalur yang baik untuk membangun aplikasi web yang aman.
Learn/routing
Routing
Catatan: Ingin memahami lebih lanjut tentang routing? Periksa halaman "mengapa sebuah framework?" untuk penjelasan yang lebih mendalam.
Routing dasar di Flight dilakukan dengan mencocokkan pola URL dengan fungsi callback atau sebuah array dari sebuah kelas dan metode.
Flight::route('/', function(){
echo 'hello world!';
});
Rute dicocokkan dalam urutan mereka didefinisikan. Rute pertama yang mencocokkan permintaan akan dipanggil.
Callback/Fungsi
Callback dapat berupa objek apa pun yang dapat dipanggil. Jadi Anda dapat menggunakan fungsi biasa:
function hello() {
echo 'hello world!';
}
Flight::route('/', 'hello');
Kelas
Anda juga dapat menggunakan metode statis dari sebuah kelas:
class Greeting {
public static function hello() {
echo 'hello world!';
}
}
Flight::route('/', [ 'Greeting','hello' ]);
Atau dengan membuat objek terlebih dahulu dan kemudian memanggil metode:
// Greeting.php
class Greeting
{
public function __construct() {
$this->name = 'John Doe';
}
public function hello() {
echo "Hello, {$this->name}!";
}
}
// index.php
$greeting = new Greeting();
Flight::route('/', [ $greeting, 'hello' ]);
// Anda juga dapat melakukan ini tanpa membuat objek terlebih dahulu
// Catatan: Tidak ada argumen yang akan disuntikkan ke konstruktor
Flight::route('/', [ 'Greeting', 'hello' ]);
// Selain itu, Anda dapat menggunakan sintaks lebih pendek ini
Flight::route('/', 'Greeting->hello');
// atau
Flight::route('/', Greeting::class.'->hello');
Dependency Injection melalui DIC (Dependency Injection Container)
Jika Anda ingin menggunakan dependency injection melalui sebuah container (PSR-11, PHP-DI, Dice, dll), satu-satunya jenis rute yang tersedia adalah langsung membuat objek sendiri dan menggunakan container untuk membuat objek Anda atau Anda dapat menggunakan string untuk mendefinisikan kelas dan metode yang akan dipanggil. Anda dapat pergi ke halaman Dependency Injection untuk informasi lebih lanjut.
Berikut adalah contoh cepat:
use flight\database\PdoWrapper;
// Greeting.php
class Greeting
{
protected PdoWrapper $pdoWrapper;
public function __construct(PdoWrapper $pdoWrapper) {
$this->pdoWrapper = $pdoWrapper;
}
public function hello(int $id) {
// lakukan sesuatu dengan $this->pdoWrapper
$name = $this->pdoWrapper->fetchField("SELECT name FROM users WHERE id = ?", [ $id ]);
echo "Hello, world! Nama saya adalah {$name}!";
}
}
// index.php
// Siapkan container dengan parameter apa pun yang Anda butuhkan
// Lihat halaman Dependency Injection untuk informasi lebih lanjut tentang PSR-11
$dice = new \Dice\Dice();
// Jangan lupa untuk menetapkan kembali variabel dengan '$dice = '!!!!!
$dice = $dice->addRule('flight\database\PdoWrapper', [
'shared' => true,
'constructParams' => [
'mysql:host=localhost;dbname=test',
'root',
'password'
]
]);
// Daftarkan pengendali container
Flight::registerContainerHandler(function($class, $params) use ($dice) {
return $dice->create($class, $params);
});
// Rute seperti biasa
Flight::route('/hello/@id', [ 'Greeting', 'hello' ]);
// atau
Flight::route('/hello/@id', 'Greeting->hello');
// atau
Flight::route('/hello/@id', 'Greeting::hello');
Flight::start();
Metode Routing
Secara default, pola rute dicocokkan dengan semua metode permintaan. Anda dapat merespons metode tertentu dengan menempatkan pengenal sebelum URL.
Flight::route('GET /', function () {
echo 'Saya menerima permintaan GET.';
});
Flight::route('POST /', function () {
echo 'Saya menerima permintaan POST.';
});
// Anda tidak dapat menggunakan Flight::get() untuk rute karena itu adalah metode
// untuk mendapatkan variabel, tidak membuat rute.
// Flight::post('/', function() { /* kode */ });
// Flight::patch('/', function() { /* kode */ });
// Flight::put('/', function() { /* kode */ });
// Flight::delete('/', function() { /* kode */ });
Anda juga dapat memetakan beberapa metode ke satu callback dengan menggunakan pemisah |
:
Flight::route('GET|POST /', function () {
echo 'Saya menerima baik permintaan GET atau POST.';
});
Selain itu, Anda dapat mengambil objek Router yang memiliki beberapa metode pembantu untuk Anda gunakan:
$router = Flight::router();
// memetakan semua metode
$router->map('/', function() {
echo 'hello world!';
});
// permintaan GET
$router->get('/users', function() {
echo 'users';
});
// $router->post();
// $router->put();
// $router->delete();
// $router->patch();
Ekspresi Reguler
Anda dapat menggunakan ekspresi reguler dalam rute Anda:
Flight::route('/user/[0-9]+', function () {
// Ini akan mencocokkan /user/1234
});
Meskipun metode ini tersedia, disarankan untuk menggunakan parameter bernama, atau parameter bernama dengan ekspresi reguler, karena lebih mudah dibaca dan lebih mudah untuk dipelihara.
Parameter Bernama
Anda dapat menentukan parameter bernama dalam rute Anda yang akan diteruskan ke fungsi callback Anda. Ini lebih untuk keterbacaan rute daripada yang lain . Silakan lihat bagian di bawah tentang caveat penting.
Flight::route('/@name/@id', function (string $name, string $id) {
echo "hello, $name ($id)!";
});
Anda juga dapat menyertakan ekspresi reguler dengan parameter bernama Anda menggunakan
pemisah :
:
Flight::route('/@name/@id:[0-9]{3}', function (string $name, string $id) {
// Ini akan mencocokkan /bob/123
// Tetapi tidak akan mencocokkan /bob/12345
});
Catatan: Mencocokkan grup regex
()
dengan parameter posisi tidak didukung. :'(
Caveat Penting
Meskipun dalam contoh di atas, tampaknya @name
terikat langsung pada variabel $name
, itu tidak. Urutan parameter dalam fungsi callback yang menentukan apa yang diteruskan ke dalamnya. Jadi jika Anda membalik urutan parameter dalam fungsi callback, variabel juga akan dibalik. Berikut adalah contohnya:
Flight::route('/@name/@id', function (string $id, string $name) {
echo "hello, $name ($id)!";
});
Dan jika Anda mengunjungi URL berikut: /bob/123
, hasilnya akan menjadi hello, 123 (bob)!
.
Silakan berhati-hati saat Anda menetapkan rute dan fungsi callback Anda.
Parameter Opsional
Anda dapat menentukan parameter bernama yang bersifat opsional untuk pencocokan dengan membungkus segmen dalam tanda kurung.
Flight::route(
'/blog(/@year(/@month(/@day)))',
function(?string $year, ?string $month, ?string $day) {
// Ini akan mencocokkan URL berikut:
// /blog/2012/12/10
// /blog/2012/12
// /blog/2012
// /blog
}
);
Parameter opsional yang tidak dicocokkan akan diteruskan sebagai NULL
.
Wildcards
Pencocokan hanya dilakukan pada segmen URL individu. Jika Anda ingin mencocokkan beberapa
segmen Anda dapat menggunakan wildcard *
.
Flight::route('/blog/*', function () {
// Ini akan mencocokkan /blog/2000/02/01
});
Untuk merutekan semua permintaan ke satu callback, Anda dapat melakukan:
Flight::route('*', function () {
// Lakukan sesuatu
});
Menyampaikan
Anda dapat meneruskan eksekusi ke rute berikutnya yang cocok dengan mengembalikan true
dari
fungsi callback Anda.
Flight::route('/user/@name', function (string $name) {
// Periksa beberapa kondisi
if ($name !== "Bob") {
// Lanjutkan ke rute berikutnya
return true;
}
});
Flight::route('/user/*', function () {
// Ini akan dipanggil
});
Aliasing Rute
Anda dapat menetapkan alias ke sebuah rute, sehingga URL dapat dibuat secara dinamis dilanjutkan dalam kode Anda (seperti template misalnya).
Flight::route('/users/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
// nanti dalam kode di suatu tempat
Flight::getUrl('user_view', [ 'id' => 5 ]); // akan mengembalikan '/users/5'
Ini sangat membantu jika URL Anda kebetulan berubah. Dalam contoh di atas, katakanlah bahwa pengguna dipindahkan ke /admin/users/@id
alih-alih.
Dengan aliasing di tempat, Anda tidak perlu mengubah di mana pun Anda merujuk alias karena alias sekarang akan mengembalikan /admin/users/5
seperti dalam
contoh di atas.
Aliasing rute masih berfungsi dalam grup juga:
Flight::group('/users', function() {
Flight::route('/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
});
// nanti dalam kode di suatu tempat
Flight::getUrl('user_view', [ 'id' => 5 ]); // akan mengembalikan '/users/5'
Informasi Rute
Jika Anda ingin memeriksa informasi rute yang cocok, Anda dapat meminta objek rute
untuk diteruskan ke fungsi callback Anda dengan meneruskan true
sebagai parameter ketiga di metode rute. Objek rute akan selalu menjadi parameter terakhir yang diteruskan ke fungsi callback Anda.
Flight::route('/', function(\flight\net\Route $route) {
// Array metode HTTP yang dicocokkan
$route->methods;
// Array parameter bernama
$route->params;
// Ekspresi reguler yang cocok
$route->regex;
// Berisi konten dari setiap '*' yang digunakan dalam pola URL
$route->splat;
// Menunjukkan jalur url....jika Anda benar-benar membutuhkannya
$route->pattern;
// Menunjukkan middleware apa yang ditugaskan untuk ini
$route->middleware;
// Menunjukkan alias yang ditugaskan untuk rute ini
$route->alias;
}, true);
Pengelompokan Rute
Mungkin ada waktu ketika Anda ingin mengelompokkan rute-rute terkait bersama (seperti /api/v1
).
Anda dapat melakukan ini dengan menggunakan metode group
:
Flight::group('/api/v1', function () {
Flight::route('/users', function () {
// Mencocokkan /api/v1/users
});
Flight::route('/posts', function () {
// Mencocokkan /api/v1/posts
});
});
Anda bahkan dapat menelurkan grup dari grup:
Flight::group('/api', function () {
Flight::group('/v1', function () {
// Flight::get() mendapatkan variabel, itu tidak menetapkan rute! Lihat konteks objek di bawah
Flight::route('GET /users', function () {
// Mencocokkan GET /api/v1/users
});
Flight::post('/posts', function () {
// Mencocokkan POST /api/v1/posts
});
Flight::put('/posts/1', function () {
// Mencocokkan PUT /api/v1/posts
});
});
Flight::group('/v2', function () {
// Flight::get() mendapatkan variabel, itu tidak menetapkan rute! Lihat konteks objek di bawah
Flight::route('GET /users', function () {
// Mencocokkan GET /api/v2/users
});
});
});
Pengelompokan dengan Konteks Objek
Anda masih dapat menggunakan pengelompokan rute dengan objek Engine
dengan cara berikut:
$app = new \flight\Engine();
$app->group('/api/v1', function (Router $router) {
// gunakan variabel $router
$router->get('/users', function () {
// Mencocokkan GET /api/v1/users
});
$router->post('/posts', function () {
// Mencocokkan POST /api/v1/posts
});
});
Resource Routing
Anda dapat membuat serangkaian rute untuk sebuah sumber daya menggunakan metode resource
. Ini akan membuat
serangkaian rute untuk sumber daya yang mengikuti konvensi RESTful.
Untuk membuat sumber daya, lakukan hal berikut:
Flight::resource('/users', UsersController::class);
Dan yang akan terjadi di latar belakang adalah ini akan membuat rute berikut:
[
'index' => 'GET ',
'create' => 'GET /create',
'store' => 'POST ',
'show' => 'GET /@id',
'edit' => 'GET /@id/edit',
'update' => 'PUT /@id',
'destroy' => 'DELETE /@id'
]
Dan controller Anda akan terlihat seperti ini:
class UsersController
{
public function index(): void
{
}
public function show(string $id): void
{
}
public function create(): void
{
}
public function store(): void
{
}
public function edit(string $id): void
{
}
public function update(string $id): void
{
}
public function destroy(string $id): void
{
}
}
Catatan: Anda dapat melihat rute yang baru ditambahkan dengan
runway
dengan menjalankanphp runway routes
.
Menyesuaikan Rute Sumber Daya
Ada beberapa opsi untuk mengonfigurasi rute sumber daya.
Alias Basis
Anda dapat mengonfigurasi aliasBase
. Secara default, alias adalah bagian terakhir dari URL yang ditentukan.
Misalnya /users/
akan menghasilkan aliasBase
menjadi users
. Ketika rute ini dibuat,
alias adalah users.index
, users.create
, dst. Jika Anda ingin mengubah alias, atur aliasBase
ke nilai yang Anda inginkan.
Flight::resource('/users', UsersController::class, [ 'aliasBase' => 'user' ]);
Hanya dan Kecuali
Anda juga dapat menentukan rute mana yang ingin Anda buat dengan menggunakan opsi only
dan except
.
Flight::resource('/users', UsersController::class, [ 'only' => [ 'index', 'show' ] ]);
Flight::resource('/users', UsersController::class, [ 'except' => [ 'create', 'store', 'edit', 'update', 'destroy' ] ]);
Ini pada dasarnya adalah opsi daftar putih dan daftar hitam sehingga Anda dapat menentukan rute mana yang ingin Anda buat.
Middleware
Anda juga dapat menentukan middleware yang akan dijalankan di setiap rute yang dibuat oleh metode resource
.
Flight::resource('/users', UsersController::class, [ 'middleware' => [ MyAuthMiddleware::class ] ]);
Streaming
Anda sekarang dapat melakukan streaming respons ke klien menggunakan metode streamWithHeaders()
.
Ini berguna untuk mengirim file besar, proses yang memakan waktu lama, atau menghasilkan respons besar.
Streaming rute ditangani sedikit berbeda dari rute biasa.
Catatan: Streaming respons hanya tersedia jika Anda memiliki
flight.v2.output_buffering
disetel ke false.
Stream dengan Header Manual
Anda dapat melakukan streaming respons ke klien dengan menggunakan metode stream()
pada sebuah rute. Jika Anda
melakukan ini, Anda harus menetapkan semua metode secara manual sebelum Anda mengeluarkan apapun kepada klien.
Ini dilakukan dengan fungsi header()
php atau metode Flight::response()->setRealHeader()
.
Flight::route('/@filename', function($filename) {
// jelas Anda akan menyaring jalur dan lain-lain.
$fileNameSafe = basename($filename);
// Jika Anda memiliki header tambahan untuk diatur di sini setelah rute dieksekusi
// Anda harus mendefinisikannya sebelum ada yang di-echo keluar.
// Mereka semua harus merupakan panggilan mentah ke fungsi header()
// atau panggilan ke Flight::response()->setRealHeader()
header('Content-Disposition: attachment; filename="'.$fileNameSafe.'"');
// atau
Flight::response()->setRealHeader('Content-Disposition', 'attachment; filename="'.$fileNameSafe.'"');
$fileData = file_get_contents('/some/path/to/files/'.$fileNameSafe);
// Penanganan kesalahan dan lain-lain
if(empty($fileData)) {
Flight::halt(404, 'File tidak ditemukan');
}
// set panjang konten secara manual jika Anda suka
header('Content-Length: '.filesize($filename));
// Streaming data ke klien
echo $fileData;
// Ini adalah baris ajaib di sini
})->stream();
Stream dengan Header
Anda juga dapat menggunakan metode streamWithHeaders()
untuk mengatur header sebelum Anda mulai streaming.
Flight::route('/stream-users', function() {
// Anda dapat menambahkan header tambahan apa pun yang Anda inginkan di sini
// Anda hanya harus menggunakan header() atau Flight::response()->setRealHeader()
// namun cara Anda menarik data Anda, hanya sebagai contoh...
$users_stmt = Flight::db()->query("SELECT id, first_name, last_name FROM users");
echo '{';
$user_count = count($users);
while($user = $users_stmt->fetch(PDO::FETCH_ASSOC)) {
echo json_encode($user);
if(--$user_count > 0) {
echo ',';
}
// Ini diperlukan untuk mengirim data ke klien
ob_flush();
}
echo '}';
// Ini adalah bagaimana Anda mengatur header sebelum Anda mulai streaming.
})->streamWithHeaders([
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename="users.json"',
// kode status opsional, default ke 200
'status' => 200
]);
Learn/flight_vs_symfony
Flight vs Symfony
Apa itu Symfony?
Symfony adalah sekumpulan komponen PHP yang dapat digunakan kembali dan framework PHP untuk proyek web.
Landasan standar di mana aplikasi PHP terbaik dibangun. Pilih salah satu dari 50 komponen mandiri yang tersedia untuk aplikasi Anda sendiri.
Percepat pembuatan dan pemeliharaan aplikasi web PHP Anda. Akhiri tugas pengkodean yang repetitif dan nikmati kekuatan mengendalikan kode Anda.
Kelebihan dibandingkan Flight
- Symfony memiliki ekosistem yang besar dari pengembang dan modul yang dapat digunakan untuk menyelesaikan masalah umum.
- Symfony memiliki ORM yang dilengkapi dengan fitur lengkap (Doctrine) yang dapat digunakan untuk berinteraksi dengan basis data Anda.
- Symfony memiliki banyak dokumentasi dan tutorial yang dapat digunakan untuk mempelajari framework.
- Symfony memiliki podcast, konferensi, pertemuan, video, dan sumber daya lainnya yang dapat digunakan untuk mempelajari framework.
- Symfony ditujukan untuk pengembang berpengalaman yang ingin membangun aplikasi web perusahaan yang kaya fitur.
Kekurangan dibandingkan Flight
- Symfony memiliki lebih banyak yang terjadi di bawah permukaan dibandingkan dengan Flight. Ini datang dengan biaya dramatis dalam hal kinerja. Lihat pengujian TechEmpower untuk informasi lebih lanjut.
- Flight ditujukan untuk pengembang yang ingin membangun aplikasi web yang ringan, cepat, dan mudah digunakan.
- Flight ditujukan untuk kesederhanaan dan kemudahan penggunaan.
- Salah satu fitur inti Flight adalah bahwa ia melakukan yang terbaik untuk mempertahankan kompatibilitas mundur.
- Flight tidak memiliki ketergantungan, sementara Symfony memiliki sejumlah ketergantungan
- Flight ditujukan untuk pengembang yang baru memasuki dunia framework untuk pertama kalinya.
- Flight juga dapat digunakan untuk aplikasi tingkat enterprise, tetapi tidak memiliki sebanyak contoh dan tutorial seperti Symfony. Ini juga akan memerlukan lebih banyak disiplin dari pihak pengembang untuk menjaga agar segala sesuatunya terorganisir dan terstruktur dengan baik.
- Flight memberikan pengembang lebih banyak kontrol atas aplikasi, sementara Symfony dapat menyisipkan sedikit keajaiban di belakang layar.
Learn/flight_vs_another_framework
Membandingkan Flight dengan Framework Lain
Jika Anda bermigrasi dari framework lain seperti Laravel, Slim, Fat-Free, atau Symfony ke Flight, halaman ini akan membantu Anda memahami perbedaan antara keduanya.
Laravel
Laravel adalah framework yang penuh fitur yang memiliki segala fasilitas dan ekosistem yang menakjubkan yang berfokus pada pengembang, tetapi dengan biaya dalam kinerja dan kompleksitas.
Lihat perbandingan antara Laravel dan Flight.
Slim
Slim adalah micro-framework yang mirip dengan Flight. Ini dirancang agar ringan dan mudah digunakan, tetapi bisa sedikit lebih kompleks daripada Flight.
Lihat perbandingan antara Slim dan Flight.
Fat-Free
Fat-Free adalah framework full-stack dalam paket yang jauh lebih kecil. Meskipun memiliki semua alat dalam kotak perkakas, ia memiliki arsitektur data yang dapat membuat beberapa proyek menjadi lebih kompleks daripada yang seharusnya.
Lihat perbandingan antara Fat-Free dan Flight.
Symfony
Symfony adalah framework modular tingkat perusahaan yang dirancang untuk fleksibel dan skalabel. Untuk proyek yang lebih kecil atau pengembang yang lebih baru, Symfony bisa sedikit membingungkan.
Lihat perbandingan antara Symfony dan Flight.
Learn/dependency_injection_container
Kontainer Penyuntikan Ketergantungan
Pengenalan
Kontainer Penyuntikan Ketergantungan (DIC) adalah alat yang kuat yang memungkinkan Anda untuk mengelola ketergantungan aplikasi Anda. Ini adalah konsep kunci dalam kerangka PHP modern dan digunakan untuk mengelola instansiasi dan konfigurasi objek. Beberapa contoh pustaka DIC adalah: Dice, Pimple, PHP-DI, dan league/container.
DIC adalah cara mewah untuk mengatakan bahwa ia memungkinkan Anda untuk membuat dan mengelola kelas Anda di lokasi terpusat. Ini berguna ketika Anda perlu mengoper objek yang sama ke beberapa kelas (seperti pengontrol Anda). Contoh sederhana mungkin membantu ini menjadi lebih jelas.
Contoh Dasar
Cara lama dalam melakukan sesuatu mungkin terlihat seperti ini:
require 'vendor/autoload.php';
// kelas untuk mengelola pengguna dari database
class UserController {
protected PDO $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function view(int $id) {
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $id]);
print_r($stmt->fetch());
}
}
$User = new UserController(new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'));
Flight::route('/user/@id', [ $UserController, 'view' ]);
Flight::start();
Anda dapat melihat dari kode di atas bahwa kami membuat objek PDO
baru dan mengoperasikan
ke kelas UserController
kami. Ini baik untuk aplikasi kecil, tetapi seiring pertumbuhan aplikasi Anda,
Anda akan menemukan bahwa Anda membuat objek PDO
yang sama di beberapa tempat. Inilah saatnya DIC berguna.
Berikut adalah contoh yang sama menggunakan DIC (menggunakan Dice):
require 'vendor/autoload.php';
// kelas yang sama seperti di atas. Tidak ada yang berubah
class UserController {
protected PDO $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function view(int $id) {
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $id]);
print_r($stmt->fetch());
}
}
// buat kontainer baru
$container = new \Dice\Dice;
// jangan lupa untuk menetapkannya kembali ke dirinya sendiri seperti di bawah ini!
$container = $container->addRule('PDO', [
// dibagikan berarti objek yang sama akan dikembalikan setiap kali
'shared' => true,
'constructParams' => ['mysql:host=localhost;dbname=test', 'user', 'pass' ]
]);
// Ini mendaftarkan penangan kontainer sehingga Flight tahu untuk menggunakannya.
Flight::registerContainerHandler(function($class, $params) use ($container) {
return $container->create($class, $params);
});
// sekarang kita bisa menggunakan kontainer untuk membuat UserController kita
Flight::route('/user/@id', [ 'UserController', 'view' ]);
// atau alternatifnya, Anda dapat mendefinisikan rute seperti ini
Flight::route('/user/@id', 'UserController->view');
// atau
Flight::route('/user/@id', 'UserController::view');
Flight::start();
Saya yakin Anda mungkin berpikir bahwa banyak kode tambahan ditambahkan ke contoh ini.
Keajaiban datang ketika Anda memiliki pengontrol lain yang membutuhkan objek PDO
.
// Jika semua pengontrol Anda memiliki konstruktor yang membutuhkan objek PDO
// masing-masing rute di bawah ini akan secara otomatis menginjeksikannya!!!
Flight::route('/company/@id', 'CompanyController->view');
Flight::route('/organization/@id', 'OrganizationController->view');
Flight::route('/category/@id', 'CategoryController->view');
Flight::route('/settings', 'SettingsController->view');
Bonus tambahan dari memanfaatkan DIC adalah bahwa pengujian unit menjadi jauh lebih mudah. Anda dapat membuat objek tiruan dan mengoperasikannya ke kelas Anda. Ini adalah manfaat besar ketika Anda menulis tes untuk aplikasi Anda!
PSR-11
Flight juga dapat menggunakan kontainer yang sesuai dengan PSR-11. Ini berarti Anda dapat menggunakan kontainer apa pun yang mengimplementasikan antarmuka PSR-11. Berikut adalah contoh menggunakan kontainer PSR-11 dari League:
require 'vendor/autoload.php';
// kelas UserController yang sama seperti di atas
$container = new \League\Container\Container();
$container->add(UserController::class)->addArgument(PdoWrapper::class);
$container->add(PdoWrapper::class)
->addArgument('mysql:host=localhost;dbname=test')
->addArgument('user')
->addArgument('pass');
Flight::registerContainerHandler($container);
Flight::route('/user', [ 'UserController', 'view' ]);
Flight::start();
Ini mungkin sedikit lebih panjang daripada contoh Dice sebelumnya, tetapi tetap menyelesaikan pekerjaan dengan keuntungan yang sama!
Penangan DIC Kustom
Anda juga dapat membuat penangan DIC Anda sendiri. Ini berguna jika Anda memiliki kontainer kustom yang ingin Anda gunakan yang bukan PSR-11 (Dice). Lihat contoh dasar untuk cara melakukannya.
Selain itu, ada beberapa default yang berguna yang akan membuat hidup Anda lebih mudah saat menggunakan Flight.
Instance Engine
Jika Anda menggunakan instance Engine
di pengontrol/middleware Anda, inilah cara Anda mengkonfigurasinya:
// Di suatu tempat di file bootstrap Anda
$engine = Flight::app();
$container = new \Dice\Dice;
$container = $container->addRule('*', [
'substitutions' => [
// Ini adalah tempat Anda mengoper instance
Engine::class => $engine
]
]);
$engine->registerContainerHandler(function($class, $params) use ($container) {
return $container->create($class, $params);
});
// Sekarang Anda dapat menggunakan instance Engine di pengontrol/middleware Anda
class MyController {
public function __construct(Engine $app) {
$this->app = $app;
}
public function index() {
$this->app->render('index');
}
}
Menambahkan Kelas Lain
Jika Anda memiliki kelas lain yang ingin Anda tambahkan ke kontainer, dengan Dice sangat mudah karena mereka akan secara otomatis diselesaikan oleh kontainer. Berikut adalah contohnya:
$container = new \Dice\Dice;
// Jika Anda tidak perlu menyuntikkan apa pun ke dalam kelas Anda
// Anda tidak perlu mendefinisikan apa pun!
Flight::registerContainerHandler(function($class, $params) use ($container) {
return $container->create($class, $params);
});
class MyCustomClass {
public function parseThing() {
return 'thing';
}
}
class UserController {
protected MyCustomClass $MyCustomClass;
public function __construct(MyCustomClass $MyCustomClass) {
$this->MyCustomClass = $MyCustomClass;
}
public function index() {
echo $this->MyCustomClass->parseThing();
}
}
Flight::route('/user', 'UserController->index');
Learn/middleware
Middleware Rute
Flight mendukung middleware rute dan group rute. Middleware adalah fungsi yang dijalankan sebelum (atau setelah) callback rute. Ini adalah cara yang bagus untuk menambahkan pemeriksaan otentikasi API dalam kode Anda, atau untuk memvalidasi bahwa pengguna memiliki izin untuk mengakses rute tersebut.
Middleware Dasar
Berikut adalah contoh dasar:
// Jika Anda hanya menyediakan fungsi anonim, itu akan dieksekusi sebelum callback rute.
// tidak ada fungsi middleware "setelah" kecuali untuk kelas (lihat di bawah)
Flight::route('/path', function() { echo ' Di sini saya!'; })->addMiddleware(function() {
echo 'Middleware pertama!';
});
Flight::start();
// Ini akan menghasilkan "Middleware pertama! Di sini saya!"
Ada beberapa catatan yang sangat penting tentang middleware yang harus Anda ketahui sebelum menggunakannya:
- Fungsi middleware dieksekusi dalam urutan mereka ditambahkan ke rute. Eksekusi mirip dengan bagaimana Slim Framework menangani ini.
- Sebelum dieksekusi dalam urutan ditambahkan, dan Setelah dieksekusi dalam urutan terbalik.
- Jika fungsi middleware Anda mengembalikan false, semua eksekusi dihentikan dan kesalahan 403 Forbidden akan dibuang. Anda mungkin ingin menangani ini secara lebih halus dengan
Flight::redirect()
atau sesuatu yang serupa. - Jika Anda perlu parameter dari rute Anda, mereka akan diteruskan dalam satu array ke fungsi middleware Anda. (
function($params) { ... }
ataupublic function before($params) {}
). Alasan untuk ini adalah Anda dapat menyusun parameter Anda dalam kelompok dan dalam beberapa kelompok tersebut, parameter Anda mungkin sebenarnya muncul dalam urutan yang berbeda yang akan merusak fungsi middleware dengan merujuk pada parameter yang salah. Dengan cara ini, Anda dapat mengaksesnya berdasarkan nama alih-alih posisi. - Jika Anda hanya memberikan nama middleware, itu akan secara otomatis dieksekusi oleh kontainer injeksi ketergantungan dan middleware akan dieksekusi dengan parameter yang dibutuhkannya. Jika Anda tidak memiliki kontainer injeksi ketergantungan yang terdaftar, itu akan meneruskan instance
flight\Engine
ke__construct()
.
Kelas Middleware
Middleware dapat terdaftar sebagai kelas juga. Jika Anda perlu fungsi "setelah", Anda harus menggunakan kelas.
class MyMiddleware {
public function before($params) {
echo 'Middleware pertama!';
}
public function after($params) {
echo 'Middleware terakhir!';
}
}
$MyMiddleware = new MyMiddleware();
Flight::route('/path', function() { echo ' Di sini saya! '; })->addMiddleware($MyMiddleware); // juga ->addMiddleware([ $MyMiddleware, $MyMiddleware2 ]);
Flight::start();
// Ini akan menampilkan "Middleware pertama! Di sini saya! Middleware terakhir!"
Menangani Kesalahan Middleware
Misalkan Anda memiliki middleware otentikasi dan Anda ingin mengalihkan pengguna ke halaman login jika mereka tidak terautentikasi. Anda memiliki beberapa opsi di tangan Anda:
- Anda dapat mengembalikan false dari fungsi middleware dan Flight akan secara otomatis mengembalikan kesalahan 403 Forbidden, tetapi tidak ada kustomisasi.
- Anda dapat mengalihkan pengguna ke halaman login menggunakan
Flight::redirect()
. - Anda dapat membuat kesalahan kustom dalam middleware dan menghentikan eksekusi rute.
Contoh Dasar
Ini adalah contoh sederhana return false;:
class MyMiddleware {
public function before($params) {
if (isset($_SESSION['user']) === false) {
return false;
}
// karena ini benar, semuanya akan terus berjalan
}
}
Contoh Redirect
Ini adalah contoh mengalihkan pengguna ke halaman login:
class MyMiddleware {
public function before($params) {
if (isset($_SESSION['user']) === false) {
Flight::redirect('/login');
exit;
}
}
}
Contoh Kesalahan Kustom
Misalkan Anda perlu membuang kesalahan JSON karena Anda sedang membangun API. Anda dapat melakukannya seperti ini:
class MyMiddleware {
public function before($params) {
$authorization = Flight::request()->headers['Authorization'];
if(empty($authorization)) {
Flight::jsonHalt(['error' => 'Anda harus masuk untuk mengakses halaman ini.'], 403);
// atau
Flight::json(['error' => 'Anda harus masuk untuk mengakses halaman ini.'], 403);
exit;
// atau
Flight::halt(403, json_encode(['error' => 'Anda harus masuk untuk mengakses halaman ini.']));
}
}
}
Pengelompokan Middleware
Anda dapat menambahkan grup rute, dan kemudian setiap rute dalam grup itu akan memiliki middleware yang sama juga. Ini berguna jika Anda perlu mengelompokkan sejumlah rute dengan misalnya middleware Auth untuk memeriksa kunci API di header.
// ditambahkan di akhir metode grup
Flight::group('/api', function() {
// Rute yang "kosong" ini sebenarnya akan mencocokkan /api
Flight::route('', function() { echo 'api'; }, false, 'api');
// Ini akan mencocokkan /api/users
Flight::route('/users', function() { echo 'users'; }, false, 'users');
// Ini akan mencocokkan /api/users/1234
Flight::route('/users/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
}, [ new ApiAuthMiddleware() ]);
Jika Anda ingin menerapkan middleware global ke semua rute Anda, Anda dapat menambahkan grup "kosong":
// ditambahkan di akhir metode grup
Flight::group('', function() {
// Ini masih /users
Flight::route('/users', function() { echo 'users'; }, false, 'users');
// Dan ini masih /users/1234
Flight::route('/users/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
}, [ new ApiAuthMiddleware() ]);
Learn/filtering
Penyaringan
Flight memungkinkan Anda untuk menyaring metode sebelum dan setelah mereka dipanggil. Tidak ada hook yang telah ditentukan sebelumnya yang perlu Anda ingat. Anda dapat menyaring salah satu dari metode kerangka kerja default serta metode kustom apa pun yang telah Anda peta.
Fungsi filter terlihat seperti ini:
function (array &$params, string &$output): bool {
// Kode penyaring
}
Dengan menggunakan variabel yang diteruskan, Anda dapat memanipulasi parameter input dan/atau output.
Anda dapat menjalankan filter sebelum sebuah metode dengan melakukan:
Flight::before('start', function (array &$params, string &$output): bool {
// Lakukan sesuatu
});
Anda dapat menjalankan filter setelah sebuah metode dengan melakukan:
Flight::after('start', function (array &$params, string &$output): bool {
// Lakukan sesuatu
});
Anda dapat menambahkan sebanyak mungkin filter yang Anda inginkan ke metode mana pun. Mereka akan dipanggil dalam urutan di mana mereka dideklarasikan.
Berikut adalah contoh proses penyaringan:
// Peta metode kustom
Flight::map('hello', function (string $name) {
return "Halo, $name!";
});
// Tambahkan filter sebelum
Flight::before('hello', function (array &$params, string &$output): bool {
// Manipulasi parameter
$params[0] = 'Fred';
return true;
});
// Tambahkan filter setelah
Flight::after('hello', function (array &$params, string &$output): bool {
// Manipulasi output
$output .= " Semoga harimu menyenangkan!";
return true;
});
// Panggil metode kustom
echo Flight::hello('Bob');
Ini seharusnya menampilkan:
Halo Fred! Semoga harimu menyenangkan!
Jika Anda telah mendefinisikan beberapa filter, Anda dapat memutus rantai dengan mengembalikan false
di salah satu fungsi filter Anda:
Flight::before('start', function (array &$params, string &$output): bool {
echo 'satu';
return true;
});
Flight::before('start', function (array &$params, string &$output): bool {
echo 'dua';
// Ini akan mengakhiri rantai
return false;
});
// Ini tidak akan dipanggil
Flight::before('start', function (array &$params, string &$output): bool {
echo 'tiga';
return true;
});
Catatan, metode inti seperti map
dan register
tidak dapat disaring karena mereka
dipanggil secara langsung dan tidak dipanggil secara dinamis.
Learn/requests
Permintaan
Flight mengenkapsulasi permintaan HTTP ke dalam satu objek, yang dapat diakses dengan melakukan:
$request = Flight::request();
Kasus Penggunaan Umum
Ketika Anda sedang bekerja dengan permintaan di aplikasi web, biasanya Anda ingin mengambil header, atau parameter $_GET
atau $_POST
, atau mungkin bahkan body permintaan mentah. Flight menyediakan antarmuka sederhana untuk melakukan semua hal ini.
Berikut adalah contoh mengambil parameter string kueri:
Flight::route('/search', function(){
$keyword = Flight::request()->query['keyword'];
echo "Anda sedang mencari: $keyword";
// kueri database atau sesuatu lainnya dengan $keyword
});
Berikut adalah contoh dari mungkin sebuah formulir dengan metode POST:
Flight::route('POST /submit', function(){
$name = Flight::request()->data['name'];
$email = Flight::request()->data['email'];
echo "Anda mengirim: $name, $email";
// simpan ke dalam database atau sesuatu lainnya dengan $name dan $email
});
Properti Objek Permintaan
Objek permintaan menyediakan properti berikut:
- body - Body permintaan HTTP mentah
- url - URL yang diminta
- base - Subdirektori induk dari URL
- method - Metode permintaan (GET, POST, PUT, DELETE)
- referrer - URL referer
- ip - Alamat IP dari klien
- ajax - Apakah permintaan adalah permintaan AJAX
- scheme - Protokol server (http, https)
- user_agent - Informasi browser
- type - Tipe konten
- length - Panjang konten
- query - Parameter string kueri
- data - Data post atau data JSON
- cookies - Data cookie
- files - File yang diunggah
- secure - Apakah koneksi aman
- accept - Parameter HTTP accept
- proxy_ip - Alamat IP proxy dari klien. Memindai array
$_SERVER
untukHTTP_CLIENT_IP
,HTTP_X_FORWARDED_FOR
,HTTP_X_FORWARDED
,HTTP_X_CLUSTER_CLIENT_IP
,HTTP_FORWARDED_FOR
,HTTP_FORWARDED
dalam urutan itu. - host - Nama host permintaan
Anda dapat mengakses properti query
, data
, cookies
, dan files
sebagai array atau objek.
Jadi, untuk mendapatkan parameter string kueri, Anda dapat melakukan:
$id = Flight::request()->query['id'];
Atau Anda dapat melakukan:
$id = Flight::request()->query->id;
Body Permintaan RAW
Untuk mendapatkan body permintaan HTTP mentah, misalnya saat menangani permintaan PUT, Anda dapat melakukan:
$body = Flight::request()->getBody();
Input JSON
Jika Anda mengirimkan permintaan dengan tipe application/json
dan data {"id": 123}
itu akan tersedia dari properti data
:
$id = Flight::request()->data->id;
$_GET
Anda dapat mengakses array $_GET
melalui properti query
:
$id = Flight::request()->query['id'];
$_POST
Anda dapat mengakses array $_POST
melalui properti data
:
$id = Flight::request()->data['id'];
$_COOKIE
Anda dapat mengakses array $_COOKIE
melalui properti cookies
:
$myCookieValue = Flight::request()->cookies['myCookieName'];
$_SERVER
Ada pintasan yang tersedia untuk mengakses array $_SERVER
melalui metode getVar()
:
$host = Flight::request()->getVar['HTTP_HOST'];
Mengakses File yang Diunggah melalui $_FILES
Anda dapat mengakses file yang diunggah melalui properti files
:
$uploadedFile = Flight::request()->files['myFile'];
Memproses Unggahan File (v3.12.0)
Anda dapat memproses unggahan file menggunakan framework dengan beberapa metode pembantu. Secara dasar, ini menyangkut mengambil data file dari permintaan, dan memindahkannya ke lokasi baru.
Flight::route('POST /upload', function(){
// Jika Anda memiliki field input seperti <input type="file" name="myFile">
$uploadedFileData = Flight::request()->getUploadedFiles();
$uploadedFile = $uploadedFileData['myFile'];
$uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
});
Jika Anda memiliki beberapa file yang diunggah, Anda dapat melakukan pengulangan melalui mereka:
Flight::route('POST /upload', function(){
// Jika Anda memiliki field input seperti <input type="file" name="myFiles[]">
$uploadedFiles = Flight::request()->getUploadedFiles()['myFiles'];
foreach ($uploadedFiles as $uploadedFile) {
$uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
}
});
Catatan Keamanan: Selalu validasi dan bersihkan input pengguna, terutama saat menangani unggahan file. Selalu validasi tipe ekstensi yang akan Anda izinkan untuk diunggah, tetapi Anda juga harus memvalidasi "magic bytes" dari file untuk memastikan file tersebut sebenarnya adalah tipe file yang diklaim pengguna. Terdapat artikel dan perpustakaan yang tersedia untuk membantu dengan ini.
Header Permintaan
Anda dapat mengakses header permintaan menggunakan metode getHeader()
atau getHeaders()
:
// Mungkin Anda membutuhkan header Authorization
$host = Flight::request()->getHeader('Authorization');
// atau
$host = Flight::request()->header('Authorization');
// Jika Anda perlu mengambil semua header
$headers = Flight::request()->getHeaders();
// atau
$headers = Flight::request()->headers();
Body Permintaan
Anda dapat mengakses body permintaan mentah menggunakan metode getBody()
:
$body = Flight::request()->getBody();
Metode Permintaan
Anda dapat mengakses metode permintaan menggunakan properti method
atau metode getMethod()
:
$method = Flight::request()->method; // sebenarnya memanggil getMethod()
$method = Flight::request()->getMethod();
Catatan: Metode getMethod()
pertama-tama menarik metode dari $_SERVER['REQUEST_METHOD']
, kemudian bisa ditimpa oleh $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']
jika ada atau $_REQUEST['_method']
jika ada.
URL Permintaan
Terdapat beberapa metode pembantu untuk menyusun bagian dari URL demi kenyamanan Anda.
URL Lengkap
Anda dapat mengakses URL permintaan penuh menggunakan metode getFullUrl()
:
$url = Flight::request()->getFullUrl();
// https://example.com/some/path?foo=bar
URL Dasar
Anda dapat mengakses URL dasar menggunakan metode getBaseUrl()
:
$url = Flight::request()->getBaseUrl();
// Perhatikan, tidak ada garis miring di akhir.
// https://example.com
Penguraian Kueri
Anda dapat mengoper URL ke metode parseQuery()
untuk menguraikan string kueri menjadi array asosiatif:
$query = Flight::request()->parseQuery('https://example.com/some/path?foo=bar');
// ['foo' => 'bar']
Learn/api
Metode API Framework
Flight dirancang agar mudah digunakan dan dipahami. Berikut adalah kumpulan lengkap metode untuk framework. Ini terdiri dari metode inti, yang merupakan metode statis biasa, dan metode yang dapat diperluas, yang merupakan metode yang dipetakan yang dapat difilter atau di-override.
Metode Inti
Metode ini adalah inti dari framework dan tidak dapat di-override.
Flight::map(string $name, callable $callback, bool $pass_route = false) // Membuat metode framework kustom.
Flight::register(string $name, string $class, array $params = [], ?callable $callback = null) // Mendaftar kelas ke metode framework.
Flight::unregister(string $name) // Mencopot pendaftaran kelas dari metode framework.
Flight::before(string $name, callable $callback) // Menambahkan filter sebelum metode framework.
Flight::after(string $name, callable $callback) // Menambahkan filter setelah metode framework.
Flight::path(string $path) // Menambahkan jalur untuk mengautoload kelas.
Flight::get(string $key) // Mendapatkan variabel yang ditetapkan oleh Flight::set().
Flight::set(string $key, mixed $value) // Mengatur variabel dalam mesin Flight.
Flight::has(string $key) // Memeriksa apakah variabel telah diatur.
Flight::clear(array|string $key = []) // Menghapus variabel.
Flight::init() // Menginisialisasi framework ke pengaturan default.
Flight::app() // Mendapatkan instance objek aplikasi.
Flight::request() // Mendapatkan instance objek permintaan.
Flight::response() // Mendapatkan instance objek respons.
Flight::router() // Mendapatkan instance objek router.
Flight::view() // Mendapatkan instance objek tampilan.
Metode yang Dapat Diperluas
Flight::start() // Memulai framework.
Flight::stop() // Menghentikan framework dan mengirimkan respons.
Flight::halt(int $code = 200, string $message = '') // Menghentikan framework dengan kode status dan pesan opsional.
Flight::route(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Memetakan pola URL ke callback.
Flight::post(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Memetakan pola URL permintaan POST ke callback.
Flight::put(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Memetakan pola URL permintaan PUT ke callback.
Flight::patch(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Memetakan pola URL permintaan PATCH ke callback.
Flight::delete(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Memetakan pola URL permintaan DELETE ke callback.
Flight::group(string $pattern, callable $callback) // Membuat pengelompokan untuk URL, pola harus berupa string.
Flight::getUrl(string $name, array $params = []) // Menghasilkan URL berdasarkan alias rute.
Flight::redirect(string $url, int $code) // Mengarahkan ke URL lain.
Flight::download(string $filePath) // Mengunduh file.
Flight::render(string $file, array $data, ?string $key = null) // Membangun file template.
Flight::error(Throwable $error) // Mengirimkan respons HTTP 500.
Flight::notFound() // Mengirimkan respons HTTP 404.
Flight::etag(string $id, string $type = 'string') // Melakukan caching HTTP ETag.
Flight::lastModified(int $time) // Melakukan caching HTTP modifikasi terakhir.
Flight::json(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Mengirimkan respons JSON.
Flight::jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Mengirimkan respons JSONP.
Flight::jsonHalt(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Mengirimkan respons JSON dan menghentikan framework.
Metode kustom yang ditambahkan dengan map
dan register
juga dapat difilter. Untuk contoh tentang cara memetakan metode ini, lihat panduan Memperluas Flight.
Learn/why_frameworks
Mengapa Kerangka?
Beberapa pemrogram sangat menentang penggunaan kerangka. Mereka berpendapat bahwa kerangka itu berlebihan, lambat, dan sulit dipelajari. Mereka mengatakan bahwa kerangka tidak diperlukan dan bahwa Anda dapat menulis kode yang lebih baik tanpa mereka. Tentu ada beberapa poin yang valid mengenai kekurangan menggunakan kerangka. Namun, ada juga banyak keuntungan dalam menggunakan kerangka.
Alasan untuk Menggunakan Kerangka
Berikut adalah beberapa alasan mengapa Anda mungkin ingin mempertimbangkan untuk menggunakan kerangka:
- Pengembangan Cepat: Kerangka menyediakan banyak fungsionalitas langsung dari kotaknya. Ini berarti Anda dapat membangun aplikasi web lebih cepat. Anda tidak perlu menulis sebanyak itu karena kerangka menyediakan banyak fungsionalitas yang Anda butuhkan.
- Konsistensi: Kerangka menyediakan cara yang konsisten untuk melakukan hal-hal. Ini memudahkan Anda untuk memahami cara kerja kode dan memudahkan pengembang lain untuk memahami kode Anda. Jika Anda memiliki skrip demi skrip, Anda mungkin kehilangan konsistensi antara skrip, terutama jika Anda bekerja dengan tim pengembang.
- Keamanan: Kerangka menyediakan fitur keamanan yang membantu melindungi aplikasi web Anda dari ancaman keamanan umum. Ini berarti Anda tidak perlu khawatir sebanyak itu tentang keamanan karena kerangka mengurus banyak hal untuk Anda.
- Komunitas: Kerangka memiliki komunitas besar pengembang yang berkontribusi pada kerangka. Ini berarti Anda dapat mendapatkan bantuan dari pengembang lain ketika Anda memiliki pertanyaan atau masalah. Ini juga berarti bahwa ada banyak sumber daya yang tersedia untuk membantu Anda belajar cara menggunakan kerangka.
- Praktik Terbaik: Kerangka dibangun menggunakan praktik terbaik. Ini berarti Anda dapat belajar dari kerangka dan menggunakan praktik terbaik yang sama dalam kode Anda sendiri. Ini dapat membantu Anda menjadi pemrogram yang lebih baik. Kadang-kadang Anda tidak tahu apa yang tidak Anda ketahui dan itu dapat merugikan Anda pada akhirnya.
- Ekstensibilitas: Kerangka dirancang untuk diperluas. Ini berarti Anda dapat menambahkan fungsionalitas Anda sendiri ke dalam kerangka. Ini memungkinkan Anda untuk membangun aplikasi web yang disesuaikan dengan kebutuhan spesifik Anda.
Flight adalah micro-framework. Ini berarti bahwa ia kecil dan ringan. Ia tidak menyediakan sebanyak fungsionalitas seperti kerangka besar seperti Laravel atau Symfony. Namun, ia menyediakan banyak fungsionalitas yang Anda butuhkan untuk membangun aplikasi web. Ini juga mudah dipelajari dan digunakan. Ini membuatnya menjadi pilihan yang baik untuk membangun aplikasi web dengan cepat dan mudah. Jika Anda baru mengenal kerangka, Flight adalah kerangka pemula yang hebat untuk mulai digunakan. Ini akan membantu Anda belajar tentang keuntungan menggunakan kerangka tanpa membebani Anda dengan terlalu banyak kompleksitas. Setelah Anda memiliki beberapa pengalaman dengan Flight, akan lebih mudah untuk beralih ke kerangka yang lebih kompleks seperti Laravel atau Symfony, namun Flight masih dapat membuat aplikasi yang berhasil dan tangguh.
Apa itu Routing?
Routing adalah inti dari kerangka Flight, tetapi apa itu sebenarnya? Routing adalah proses mengambil URL dan mencocokkannya dengan fungsi tertentu di kode Anda.
Inilah cara Anda dapat membuat situs web Anda melakukan hal-hal yang berbeda berdasarkan URL yang diminta. Misalnya, Anda mungkin ingin menampilkan profil pengguna ketika mereka
mengunjungi /user/1234
, tetapi menampilkan daftar semua pengguna ketika mereka mengunjungi /users
. Semua ini dilakukan melalui routing.
Ini mungkin bekerja seperti ini:
- Seorang pengguna pergi ke peramban Anda dan mengetik
http://example.com/user/1234
. - Server menerima permintaan dan melihat URL dan meneruskannya ke kode aplikasi Flight Anda.
- Katakanlah di kode Flight Anda Anda memiliki sesuatu seperti
Flight::route('/user/@id', [ 'UserController', 'viewUserProfile' ]);
. Kode aplikasi Flight Anda melihat URL dan melihat bahwa itu cocok dengan jalur yang telah Anda definisikan, dan kemudian menjalankan kode yang telah Anda definisikan untuk jalur tersebut. - Router Flight kemudian akan dijalankan dan memanggil metode
viewUserProfile($id)
dalam kelasUserController
, dengan melewatkan1234
sebagai argumen$id
dalam metode tersebut. - Kode dalam metode
viewUserProfile()
Anda kemudian akan dijalankan dan melakukan apa yang telah Anda katakan untuk dilakukan. Anda mungkin akan mengeluarkan beberapa HTML untuk halaman profil pengguna, atau jika ini adalah API RESTful, Anda mungkin akan mengeluarkan respons JSON dengan informasi pengguna. - Flight membungkus ini dengan rapi, menghasilkan header respons dan mengirimkannya kembali ke peramban pengguna.
- Pengguna merasa senang dan memberi diri mereka pelukan hangat!
Dan Mengapa Ini Penting?
Memiliki router terpusat yang baik sebenarnya dapat membuat hidup Anda jauh lebih mudah! Ini mungkin sulit dilihat pada awalnya. Berikut adalah beberapa alasan mengapa:
- Routing Terpusat: Anda dapat menyimpan semua jalur Anda di satu tempat. Ini memudahkan untuk melihat jalur mana yang Anda miliki dan apa yang mereka lakukan. Ini juga memudahkan untuk mengubahnya jika Anda perlu.
- Parameter Jalur: Anda dapat menggunakan parameter jalur untuk melewatkan data ke metode jalur Anda. Ini adalah cara yang bagus untuk menjaga kode Anda tetap bersih dan teratur.
- Kelompok Jalur: Anda dapat mengelompokkan jalur bersama. Ini bagus untuk menjaga kode Anda teratur dan untuk menerapkan middleware ke sekelompok jalur.
- Alias Jalur: Anda dapat menetapkan alias ke sebuah jalur, sehingga URL dapat dibuat secara dinamis nanti di kode Anda (seperti template misalnya). Contoh: alih-alih menghardcode
/user/1234
di kode Anda, Anda bisa merujuk ke aliasuser_view
dan melewatkanid
sebagai parameter. Ini sangat memudahkan jika Anda memutuskan untuk mengubahnya menjadi/admin/user/1234
nanti. Anda tidak perlu mengubah semua URL yang Anda hardcode, cukup URL yang terhubung ke jalur. - Middleware Jalur: Anda dapat menambahkan middleware ke jalur Anda. Middleware sangat kuat dalam menambahkan perilaku tertentu ke aplikasi Anda, seperti mengotentikasi bahwa pengguna tertentu dapat mengakses jalur atau kelompok jalur.
Saya yakin Anda sudah familiar dengan cara skrip demi skrip untuk membuat situs web. Anda mungkin memiliki file bernama index.php
yang memiliki banyak pernyataan if
untuk memeriksa URL dan kemudian menjalankan fungsi tertentu berdasarkan URL tersebut. Ini adalah bentuk routing, tetapi tidak sangat teratur dan dapat
menjadi tidak terkendali dengan cepat. Sistem routing Flight adalah cara yang jauh lebih teratur dan kuat untuk menangani routing.
Ini?
// /user/view_profile.php?id=1234
if ($_GET['id']) {
$id = $_GET['id'];
viewUserProfile($id);
}
// /user/edit_profile.php?id=1234
if ($_GET['id']) {
$id = $_GET['id'];
editUserProfile($id);
}
// dll...
Atau ini?
// index.php
Flight::route('/user/@id', [ 'UserController', 'viewUserProfile' ]);
Flight::route('/user/@id/edit', [ 'UserController', 'editUserProfile' ]);
// Mungkin di dalam app/controllers/UserController.php Anda
class UserController {
public function viewUserProfile($id) {
// lakukan sesuatu
}
public function editUserProfile($id) {
// lakukan sesuatu
}
}
Semoga Anda mulai melihat manfaat menggunakan sistem routing terpusat. Ini jauh lebih mudah untuk dikelola dan dipahami dalam jangka panjang!
Permintaan dan Respons
Flight menyediakan cara yang sederhana dan mudah untuk menangani permintaan dan respons. Ini adalah inti dari apa yang dilakukan kerangka web. Ini menerima permintaan dari peramban pengguna, memprosesnya, dan kemudian mengirim kembali respons. Ini adalah cara Anda dapat membangun aplikasi web yang melakukan hal-hal seperti menampilkan profil pengguna, memungkinkan pengguna masuk, atau memungkinkan pengguna membuat posting blog baru.
Permintaan
Permintaan adalah apa yang dikirim peramban pengguna ke server Anda ketika mereka mengunjungi situs web Anda. Permintaan ini mengandung informasi tentang apa yang ingin dilakukan pengguna. Misalnya, mungkin berisi informasi tentang URL apa yang ingin dikunjungi pengguna, data apa yang ingin dikirim pengguna ke server Anda, atau jenis data apa yang ingin diterima pengguna dari server Anda. Penting untuk diketahui bahwa permintaan bersifat read-only. Anda tidak dapat mengubah permintaan, tetapi Anda dapat membacanya.
Flight menyediakan cara yang sederhana untuk mengakses informasi tentang permintaan tersebut. Anda dapat mengakses informasi tentang permintaan menggunakan metode Flight::request()
. Metode ini mengembalikan objek Request
yang berisi informasi tentang permintaan. Anda dapat menggunakan objek ini untuk mengakses informasi tentang
permintaan, seperti URL, metode, atau data yang dikirim pengguna ke server Anda.
Respons
Respons adalah apa yang dikirim server Anda kembali ke peramban pengguna ketika mereka mengunjungi situs web Anda. Respons ini berisi informasi tentang apa yang ingin dilakukan server Anda. Misalnya, mungkin berisi informasi tentang jenis data apa yang ingin dikirim server Anda kepada pengguna, jenis data apa yang ingin diterima server Anda dari pengguna, atau jenis data apa yang ingin disimpan server Anda di komputer pengguna.
Flight menyediakan cara yang sederhana untuk mengirim respons ke peramban pengguna. Anda dapat mengirim respons menggunakan metode Flight::response()
. Metode ini
mengambil objek Response
sebagai argumen dan mengirimkan respons ke peramban pengguna. Anda dapat menggunakan objek ini untuk mengirim respons kepada peramban pengguna,
seperti HTML, JSON, atau file. Flight membantu Anda secara otomatis menghasilkan beberapa bagian dari respons untuk mempermudah, tetapi pada akhirnya Anda memiliki
kendali atas apa yang Anda kirim kembali kepada pengguna.
Learn/responses
Respons
Flight membantu menghasilkan sebagian dari header respons untuk Anda, tetapi Anda memegang sebagian besar kontrol atas apa yang Anda kirim kembali kepada pengguna. Terkadang Anda dapat mengakses objek Response
secara langsung, tetapi sebagian besar waktu Anda akan menggunakan instance Flight
untuk mengirim respons.
Mengirim Respons Dasar
Flight menggunakan ob_start() untuk menampung keluaran. Ini berarti Anda dapat menggunakan echo
atau print
untuk mengirim respons kepada pengguna dan Flight akan menangkapnya dan mengirimkannya kembali kepada pengguna dengan header yang sesuai.
// Ini akan mengirim "Hello, World!" ke browser pengguna
Flight::route('/', function() {
echo "Hello, World!";
});
// HTTP/1.1 200 OK
// Content-Type: text/html
//
// Hello, World!
Sebagai alternatif, Anda dapat memanggil metode write()
untuk menambahkan ke tubuh juga.
// Ini akan mengirim "Hello, World!" ke browser pengguna
Flight::route('/', function() {
// verbose, tetapi kadang-kadang menyelesaikan pekerjaan ketika Anda membutuhkannya
Flight::response()->write("Hello, World!");
// jika Anda ingin mengambil tubuh yang telah Anda atur pada titik ini
// Anda dapat melakukannya seperti ini
$body = Flight::response()->getBody();
});
Kode Status
Anda dapat mengatur kode status dari respons dengan menggunakan metode status
:
Flight::route('/@id', function($id) {
if($id == 123) {
Flight::response()->status(200);
echo "Hello, World!";
} else {
Flight::response()->status(403);
echo "Forbidden";
}
});
Jika Anda ingin mendapatkan kode status saat ini, Anda dapat menggunakan metode status
tanpa argumen:
Flight::response()->status(); // 200
Mengatur Tubuh Respons
Anda dapat mengatur tubuh respons dengan menggunakan metode write
, namun, jika Anda menggunakan echo atau print apa pun,
itu akan ditangkap dan dikirim sebagai tubuh respons melalui output buffering.
Flight::route('/', function() {
Flight::response()->write("Hello, World!");
});
// sama dengan
Flight::route('/', function() {
echo "Hello, World!";
});
Menghapus Tubuh Respons
Jika Anda ingin menghapus tubuh respons, Anda dapat menggunakan metode clearBody
:
Flight::route('/', function() {
if($someCondition) {
Flight::response()->write("Hello, World!");
} else {
Flight::response()->clearBody();
}
});
Menjalankan Callback pada Tubuh Respons
Anda dapat menjalankan callback pada tubuh respons dengan menggunakan metode addResponseBodyCallback
:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
});
// Ini akan gzip semua respons untuk rute mana pun
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
Anda dapat menambahkan beberapa callback dan mereka akan dijalankan dalam urutan di mana mereka ditambahkan. Karena ini dapat menerima callable, ini dapat menerima array kelas [ $class, 'method' ]
, penutupan $strReplace = function($body) { str_replace('hi', 'there', $body); };
, atau nama fungsi 'minify'
jika Anda memiliki fungsi untuk meminimalkan kode html Anda misalnya.
Catatan: Callback rute tidak akan berfungsi jika Anda menggunakan opsi konfigurasi flight.v2.output_buffering
.
Callback Rute Khusus
Jika Anda ingin ini hanya berlaku untuk rute tertentu, Anda dapat menambahkan callback di dalam rute itu sendiri:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
// Ini akan gzip hanya respons untuk rute ini
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
});
Opsi Middleware
Anda juga dapat menggunakan middleware untuk menerapkan callback ke semua rute melalui middleware:
// MinifyMiddleware.php
class MinifyMiddleware {
public function before() {
// Terapkan callback di sini pada objek response().
Flight::response()->addResponseBodyCallback(function($body) {
return $this->minify($body);
});
}
protected function minify(string $body): string {
// meminimalkan tubuh dengan cara tertentu
return $body;
}
}
// index.php
Flight::group('/users', function() {
Flight::route('', function() { /* ... */ });
Flight::route('/@id', function($id) { /* ... */ });
}, [ new MinifyMiddleware() ]);
Mengatur Header Respons
Anda dapat mengatur header seperti tipe konten dari respons dengan menggunakan metode header
:
// Ini akan mengirim "Hello, World!" ke browser pengguna dalam teks biasa
Flight::route('/', function() {
Flight::response()->header('Content-Type', 'text/plain');
// atau
Flight::response()->setHeader('Content-Type', 'text/plain');
echo "Hello, World!";
});
JSON
Flight menyediakan dukungan untuk mengirim respons JSON dan JSONP. Untuk mengirim respons JSON Anda mengirimkan beberapa data untuk di-JSON encode:
Flight::json(['id' => 123]);
JSON dengan Kode Status
Anda juga dapat mengirimkan kode status sebagai argumen kedua:
Flight::json(['id' => 123], 201);
JSON dengan Pretty Print
Anda juga dapat mengirimkan argumen ke posisi terakhir untuk mengaktifkan pretty printing:
Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);
Jika Anda mengubah opsi yang diteruskan ke Flight::json()
dan ingin sintaks yang lebih sederhana, Anda dapat
hanya memetakan kembali metode JSON:
Flight::map('json', function($data, $code = 200, $options = 0) {
Flight::_json($data, $code, true, 'utf-8', $options);
}
// Dan sekarang itu dapat digunakan seperti ini
Flight::json(['id' => 123], 200, JSON_PRETTY_PRINT);
JSON dan Berhenti Eksekusi (v3.10.0)
Jika Anda ingin mengirim respons JSON dan menghentikan eksekusi, Anda dapat menggunakan metode jsonHalt
.
Ini berguna untuk kasus di mana Anda memeriksa mungkin beberapa jenis otorisasi dan jika
pengguna tidak berwenang, Anda dapat segera mengirim respons JSON, menghapus konten tubuh yang ada
dan menghentikan eksekusi.
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// Periksa apakah pengguna berwenang
if($authorized === false) {
Flight::jsonHalt(['error' => 'Unauthorized'], 401);
}
// Lanjutkan dengan sisa rute
});
Sebelum v3.10.0, Anda harus melakukan sesuatu seperti ini:
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// Periksa apakah pengguna berwenang
if($authorized === false) {
Flight::halt(401, json_encode(['error' => 'Unauthorized']));
}
// Lanjutkan dengan sisa rute
});
JSONP
Untuk permintaan JSONP, Anda dapat secara opsional meneruskan nama parameter kueri yang Anda gunakan untuk mendefinisikan fungsi callback Anda:
Flight::jsonp(['id' => 123], 'q');
Jadi, ketika melakukan permintaan GET menggunakan ?q=my_func
, Anda harus menerima keluaran:
my_func({"id":123});
Jika Anda tidak meneruskan nama parameter kueri, itu akan default ke jsonp
.
Mengalihkan ke URL Lain
Anda dapat mengalihkan permintaan saat ini dengan menggunakan metode redirect()
dan meneruskan
URL baru:
Flight::redirect('/new/location');
Secara default, Flight mengirimkan kode status HTTP 303 ("Lihat Lain"). Anda dapat secara opsional mengatur kode khusus:
Flight::redirect('/new/location', 401);
Menghentikan
Anda dapat menghentikan kerangka kerja di mana saja dengan memanggil metode halt
:
Flight::halt();
Anda juga dapat menentukan kode status HTTP
dan pesan yang opsional:
Flight::halt(200, 'Be right back...');
Memanggil halt
akan membuang konten respons apa pun hingga saat itu. Jika Anda ingin menghentikan
kerangka kerja dan mengeluarkan respons saat ini, gunakan metode stop
:
Flight::stop();
Menghapus Data Respons
Anda dapat menghapus tubuh respons dan header dengan menggunakan metode clear()
. Ini akan menghapus
header apa pun yang ditetapkan ke respons, menghapus tubuh respons, dan mengatur kode status ke 200
.
Flight::response()->clear();
Menghapus Tubuh Respons Saja
Jika Anda hanya ingin menghapus tubuh respons, Anda dapat menggunakan metode clearBody()
:
// Ini akan tetap menjaga header yang telah ditetapkan pada objek response().
Flight::response()->clearBody();
Cache HTTP
Flight menyediakan dukungan bawaan untuk caching tingkat HTTP. Jika kondisi caching
terpenuhi, Flight akan mengembalikan respons HTTP 304 Not Modified
. Lain kali klien meminta sumber daya yang sama, mereka akan diminta untuk menggunakan versi cached lokal mereka.
Caching Tingkat Rute
Jika Anda ingin menyimpan seluruh respons, Anda dapat menggunakan metode cache()
dan meneruskan waktu untuk caching.
// Ini akan menyimpan respons selama 5 menit
Flight::route('/news', function () {
Flight::response()->cache(time() + 300);
echo 'Konten ini akan disimpan.';
});
// Sebagai alternatif, Anda dapat menggunakan string yang akan Anda kirimkan
// ke metode strtotime()
Flight::route('/news', function () {
Flight::response()->cache('+5 minutes');
echo 'Konten ini akan disimpan.';
});
Last-Modified
Anda dapat menggunakan metode lastModified
dan meneruskan timestamp UNIX untuk mengatur tanggal
dan waktu halaman terakhir dimodifikasi. Klien akan terus menggunakan cache mereka hingga
nilai terakhir dimodifikasi berubah.
Flight::route('/news', function () {
Flight::lastModified(1234567890);
echo 'Konten ini akan disimpan.';
});
ETag
Caching ETag
mirip dengan Last-Modified
, kecuali Anda dapat menentukan id apa pun
yang Anda inginkan untuk sumber daya:
Flight::route('/news', function () {
Flight::etag('my-unique-id');
echo 'Konten ini akan disimpan.';
});
Ingatlah bahwa memanggil baik lastModified
atau etag
akan menetapkan dan memeriksa
nilai cache. Jika nilai cache sama antara permintaan, Flight akan segera
mengirim respons HTTP 304
dan menghentikan pemrosesan.
Mengunduh File (v3.12.0)
Ada metode bantuan untuk mengunduh file. Anda dapat menggunakan metode download
dan meneruskan jalur.
Flight::route('/download', function () {
Flight::download('/path/to/file.txt');
});
Learn/templates
Tampilan dan Template HTML
Flight menyediakan beberapa fungsionalitas templating dasar secara default.
Jika Anda memerlukan kebutuhan templating yang lebih kompleks, lihat contoh Smarty dan Latte di bagian Tampilan Kustom.
Mesin Tampilan Default
Untuk menampilkan template tampilan, panggil metode render
dengan nama
file template dan data template opsional:
Flight::render('hello.php', ['name' => 'Bob']);
Data template yang Anda masukkan akan secara otomatis disuntikkan ke dalam template dan dapat
diacu seperti variabel lokal. File template hanyalah file PHP. Jika isi file template hello.php
adalah:
Hello, <?= $name ?>!
Outputnya akan menjadi:
Hello, Bob!
Anda juga dapat secara manual mengatur variabel tampilan dengan menggunakan metode set:
Flight::view()->set('name', 'Bob');
Variabel name
sekarang tersedia di semua tampilan Anda. Jadi Anda cukup melakukan:
Flight::render('hello');
Perhatikan bahwa saat menentukan nama template dalam metode render, Anda dapat
mengabaikan ekstensi .php
.
Secara default, Flight akan mencari direktori views
untuk file template. Anda dapat
mengatur jalur alternatif untuk template Anda dengan menyetel konfigurasi berikut:
Flight::set('flight.views.path', '/path/to/views');
Layout
Umum bagi situs web untuk memiliki satu file template layout dengan konten yang berganti-ganti. Untuk merender konten yang akan digunakan dalam layout, Anda dapat memberikan parameter opsional pada metode render
.
Flight::render('header', ['heading' => 'Hello'], 'headerContent');
Flight::render('body', ['body' => 'World'], 'bodyContent');
Tampilan Anda kemudian akan memiliki variabel yang disimpan bernama headerContent
dan bodyContent
.
Anda kemudian dapat merender layout Anda dengan melakukan:
Flight::render('layout', ['title' => 'Halaman Utama']);
Jika file template terlihat seperti ini:
header.php
:
<h1><?= $heading ?></h1>
body.php
:
<div><?= $body ?></div>
layout.php
:
<html>
<head>
<title><?= $title ?></title>
</head>
<body>
<?= $headerContent ?>
<?= $bodyContent ?>
</body>
</html>
Outputnya akan menjadi:
<html>
<head>
<title>Halaman Utama</title>
</head>
<body>
<h1>Hello</h1>
<div>World</div>
</body>
</html>
Mesin Tampilan Kustom
Flight memungkinkan Anda untuk mengganti mesin tampilan default hanya dengan mendaftarkan kelas tampilan Anda sendiri.
Smarty
Inilah cara Anda menggunakan mesin template Smarty untuk tampilan Anda:
// Memuat pustaka Smarty
require './Smarty/libs/Smarty.class.php';
// Mendaftarkan Smarty sebagai kelas tampilan
// Juga berikan fungsi callback untuk mengonfigurasi Smarty saat dimuat
Flight::register('view', Smarty::class, [], function (Smarty $smarty) {
$smarty->setTemplateDir('./templates/');
$smarty->setCompileDir('./templates_c/');
$smarty->setConfigDir('./config/');
$smarty->setCacheDir('./cache/');
});
// Menetapkan data template
Flight::view()->assign('name', 'Bob');
// Menampilkan template
Flight::view()->display('hello.tpl');
Untuk kelengkapan, Anda juga harus menimpa metode render default Flight:
Flight::map('render', function(string $template, array $data): void {
Flight::view()->assign($data);
Flight::view()->display($template);
});
Latte
Inilah cara Anda menggunakan mesin template Latte untuk tampilan Anda:
// Mendaftarkan Latte sebagai kelas tampilan
// Juga berikan fungsi callback untuk mengonfigurasi Latte saat dimuat
Flight::register('view', Latte\Engine::class, [], function (Latte\Engine $latte) {
// Di sinilah Latte akan menyimpan cache template Anda untuk mempercepat segalanya
// Satu hal yang menarik tentang Latte adalah bahwa ia secara otomatis menyegarkan
// cache Anda saat Anda melakukan perubahan pada template Anda!
$latte->setTempDirectory(__DIR__ . '/../cache/');
// Beritahu Latte di mana direktori root untuk tampilan Anda.
$latte->setLoader(new \Latte\Loaders\FileLoader(__DIR__ . '/../views/'));
});
// Dan menyimpulkan sehingga Anda dapat menggunakan Flight::render() dengan benar
Flight::map('render', function(string $template, array $data): void {
// Ini seperti $latte_engine->render($template, $data);
echo Flight::view()->render($template, $data);
});
Learn/flight_vs_fat_free
Flight vs Fat-Free
Apa itu Fat-Free?
Fat-Free (dikenal dengan penuh kasih sebagai F3) adalah sebuah mikro-framework PHP yang kuat namun mudah digunakan, dirancang untuk membantu Anda membangun aplikasi web yang dinamis dan tangguh - dengan cepat!
Flight dibandingkan dengan Fat-Free dalam banyak hal dan mungkin merupakan kerabat terdekat dalam hal fitur dan kesederhanaan. Fat-Free memiliki banyak fitur yang tidak dimiliki oleh Flight, tetapi juga memiliki banyak fitur yang dimiliki oleh Flight. Fat-Free mulai menunjukkan usianya dan tidak sepopuler dulu.
Pembaruan menjadi semakin jarang dan komunitas tidak seaktif dulu. Kode ini cukup sederhana, tetapi terkadang kurangnya disiplin sintaks dapat membuatnya sulit untuk dibaca dan dipahami. Ini berfungsi untuk PHP 8.3, tetapi kode itu sendiri masih terlihat seolah-olah berada di PHP 5.3.
Kelebihan dibandingkan Flight
- Fat-Free memiliki beberapa bintang lebih banyak di GitHub dibandingkan Flight.
- Fat-Free memiliki dokumentasi yang cukup baik, tetapi kurang jelas di beberapa area.
- Fat-Free memiliki beberapa sumber daya yang jarang seperti tutorial YouTube dan artikel online yang dapat digunakan untuk mempelajari framework.
- Fat-Free memiliki beberapa plugin yang berguna yang terkadang bermanfaat.
- Fat-Free memiliki ORM bawaan yang disebut Mapper yang dapat digunakan untuk berinteraksi dengan database Anda. Flight memiliki active-record.
- Fat-Free memiliki sesi, caching, dan lokalisasi bawaan. Flight mengharuskan Anda untuk menggunakan pustaka pihak ketiga, tetapi dijelaskan dalam dokumentasi.
- Fat-Free memiliki sekelompok plugin yang dibuat oleh komunitas yang dapat digunakan untuk memperluas framework. Flight memiliki beberapa yang dijelaskan dalam halaman dokumentasi dan contoh.
- Fat-Free seperti Flight tidak memiliki ketergantungan.
- Fat-Free seperti Flight ditujukan untuk memberikan kontrol kepada pengembang atas aplikasi mereka dan pengalaman pengembang yang sederhana.
- Fat-Free mempertahankan kompatibilitas ke belakang seperti halnya Flight (sebagian karena pembaruan semakin jarang).
- Fat-Free seperti Flight ditujukan untuk pengembang yang menjelajah ke dunia framework untuk pertama kalinya.
- Fat-Free memiliki mesin template bawaan yang lebih kuat dibandingkan dengan mesin template Flight. Flight merekomendasikan Latte untuk mencapai ini.
- Fat-Free memiliki perintah CLI tipe "route" unik di mana Anda dapat membangun aplikasi CLI di dalam Fat-Free itu sendiri dan memperlakukannya seperti permintaan
GET
. Flight mencapainya dengan runway.
Kekurangan dibandingkan Flight
- Fat-Free memiliki beberapa pengujian implementasi dan bahkan memiliki kelas test sendiri yang sangat dasar. Namun, tidak 100% diuji unit seperti Flight.
- Anda harus menggunakan mesin pencari seperti Google untuk benar-benar mencari situs dokumentasi.
- Flight memiliki mode gelap di situs dokumentasi mereka. (mic drop)
- Fat-Free memiliki beberapa modul yang sangat kurang terawat.
- Flight memiliki PdoWrapper yang sedikit lebih sederhana dibandingkan kelas
DB\SQL
bawaan Fat-Free. - Flight memiliki plugin izin yang dapat digunakan untuk mengamankan aplikasi Anda. Slim mengharuskan Anda untuk menggunakan pustaka pihak ketiga.
- Flight memiliki ORM yang disebut active-record yang terasa lebih seperti ORM dibandingkan dengan Mapper Fat-Free.
Manfaat tambahan dari
active-record
adalah Anda dapat mendefinisikan hubungan antara catatan untuk penggabungan otomatis di mana Mapper Fat-Free mengharuskan Anda untuk membuat tampilan SQL. - Yang mengejutkan, Fat-Free tidak memiliki namespace akar. Flight memiliki namespace yang lengkap untuk tidak bertabrakan dengan kode Anda sendiri.
kelas
Cache
adalah pelanggar terbesar di sini. - Fat-Free tidak memiliki middleware. Sebaliknya, ada hook
beforeroute
danafterroute
yang dapat digunakan untuk memfilter permintaan dan respons di dalam kontroler. - Fat-Free tidak dapat mengelompokkan routes.
- Fat-Free memiliki penangan kontainer injeksi ketergantungan, tetapi dokumentasinya sangat jarang tentang cara menggunakannya.
- Penggunaan debugging bisa sedikit rumit karena pada dasarnya semuanya disimpan dalam apa yang disebut
HIVE
.
Learn/extending
Memperpanjang
Flight dirancang untuk menjadi framework yang dapat diperluas. Framework ini dilengkapi dengan sejumlah metode dan komponen standar, tetapi memungkinkan Anda untuk memetakan metode Anda sendiri, mendaftar kelas Anda sendiri, atau bahkan menggantikan kelas dan metode yang ada.
Jika Anda mencari DIC (Dependency Injection Container), silakan menuju halaman Dependency Injection Container.
Memetakan Metode
Untuk memetakan metode kustom sederhana Anda sendiri, Anda menggunakan fungsi map
:
// Pemetaan metode Anda
Flight::map('hello', function (string $name) {
echo "hello $name!";
});
// Memanggil metode kustom Anda
Flight::hello('Bob');
Meskipun dimungkinkan untuk membuat metode kustom sederhana, disarankan untuk hanya membuat fungsi standar di PHP. Ini memiliki autocomplete di IDE dan lebih mudah dibaca. Padanan dari kode di atas adalah:
function hello(string $name) {
echo "hello $name!";
}
hello('Bob');
Ini lebih sering digunakan ketika Anda perlu melewatkan variabel ke dalam metode Anda untuk mendapatkan nilai yang diharapkan. Menggunakan metode register()
seperti di bawah ini lebih untuk melewatkan konfigurasi dan kemudian memanggil kelas yang telah dipra-konfigurasi.
Mendaftar Kelas
Untuk mendaftarkan kelas Anda sendiri dan mengonfigurasinya, Anda menggunakan fungsi register
:
// Mendaftar kelas Anda
Flight::register('user', User::class);
// Mendapatkan instance dari kelas Anda
$user = Flight::user();
Metode register juga memungkinkan Anda untuk melewatkan parameter ke konstruktor kelas Anda. Jadi ketika Anda memuat kelas kustom Anda, itu akan datang dengan pra-inisialisasi. Anda dapat mendefinisikan parameter konstruktor dengan melewatkan array tambahan. Berikut adalah contoh memuat koneksi database:
// Mendaftar kelas dengan parameter konstruktor
Flight::register('db', PDO::class, ['mysql:host=localhost;dbname=test', 'user', 'pass']);
// Mendapatkan instance dari kelas Anda
// Ini akan membuat objek dengan parameter yang telah ditentukan
//
// new PDO('mysql:host=localhost;dbname=test','user','pass');
//
$db = Flight::db();
// dan jika Anda memerlukannya nanti dalam kode Anda, Anda hanya perlu memanggil metode yang sama sekali lagi
class SomeController {
public function __construct() {
$this->db = Flight::db();
}
}
Jika Anda melewatkan parameter callback tambahan, itu akan dieksekusi segera setelah konstruktor kelas. Ini memungkinkan Anda untuk melakukan prosedur persiapan untuk objek baru Anda. Fungsi callback mengambil satu parameter, sebuah instance dari objek baru.
// Callback akan menerima objek yang telah dibangun
Flight::register(
'db',
PDO::class,
['mysql:host=localhost;dbname=test', 'user', 'pass'],
function (PDO $db) {
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
);
Secara default, setiap kali Anda memuat kelas Anda, Anda akan mendapatkan instance bersama. Untuk mendapatkan instance baru dari kelas, cukup melewatkan false
sebagai parameter:
// Instance bersama dari kelas
$shared = Flight::db();
// Instance baru dari kelas
$new = Flight::db(false);
Ingat bahwa metode yang dipetakan memiliki prioritas lebih tinggi daripada kelas yang terdaftar. Jika Anda mendeklarasikan keduanya dengan nama yang sama, hanya metode yang dipetakan yang akan dipanggil.
Mengganti Metode Framework
Flight memungkinkan Anda untuk mengganti fungsionalitas bawaannya sesuai kebutuhan Anda sendiri, tanpa harus memodifikasi kode apa pun. Anda dapat melihat semua metode yang dapat Anda ganti di sini.
Sebagai contoh, ketika Flight tidak dapat mencocokkan URL dengan rute, ia memanggil metode notFound
yang mengirimkan respons HTTP 404
umum. Anda dapat mengganti perilaku ini dengan menggunakan metode map
:
Flight::map('notFound', function() {
// Tampilkan halaman 404 kustom
include 'errors/404.html';
});
Flight juga memungkinkan Anda untuk mengganti komponen inti dari framework. Sebagai contoh, Anda dapat mengganti kelas Router standar dengan kelas kustom Anda sendiri:
// Mendaftar kelas kustom Anda
Flight::register('router', MyRouter::class);
// Ketika Flight memuat instance Router, itu akan memuat kelas Anda
$myrouter = Flight::router();
Namun, metode-framework seperti map
dan register
tidak dapat diganti. Anda akan mendapatkan kesalahan jika mencoba melakukannya.
Learn/flight_vs_slim
Flight vs Slim
Apa itu Slim?
Slim adalah kerangka mikro PHP yang membantu Anda dengan cepat menulis aplikasi web dan API yang sederhana namun kuat.
Banyak inspirasi untuk beberapa fitur v3 dari Flight sebenarnya datang dari Slim. Pengelompokan rute, dan menjalankan middleware dalam urutan tertentu adalah dua fitur yang terinspirasi oleh Slim. Slim v3 diluncurkan dengan mengutamakan kesederhanaan, tetapi terdapat ulasan campuran mengenai v4.
Kelebihan dibandingkan Flight
- Slim memiliki komunitas pengembang yang lebih besar, yang pada gilirannya membuat modul-modul berguna untuk membantu Anda tidak menciptakan kembali roda.
- Slim mengikuti banyak antarmuka dan standar yang umum di komunitas PHP, yang meningkatkan interoperabilitas.
- Slim memiliki dokumentasi dan tutorial yang baik yang dapat digunakan untuk mempelajari kerangka kerja (tidak ada yang sebanding dengan Laravel atau Symfony).
- Slim memiliki berbagai sumber daya seperti tutorial YouTube dan artikel online yang dapat digunakan untuk mempelajari kerangka kerja.
- Slim memungkinkan Anda menggunakan komponen apa pun yang Anda inginkan untuk menangani fitur routing inti karena memenuhi standar PSR-7.
Kekurangan dibandingkan Flight
- Secara mengejutkan, Slim tidak secepat yang Anda kira untuk sebuah mikro-kerangka. Lihat benchmark TechEmpower untuk informasi lebih lanjut.
- Flight ditujukan untuk pengembang yang ingin membangun aplikasi web yang ringan, cepat, dan mudah digunakan.
- Flight tidak memiliki ketergantungan, sedangkan Slim memiliki beberapa ketergantungan yang harus Anda instal.
- Flight ditujukan untuk kesederhanaan dan kemudahan penggunaan.
- Salah satu fitur inti dari Flight adalah bahwa ia melakukan yang terbaik untuk mempertahankan kompatibilitas mundur. Perubahan dari Slim v3 ke v4 adalah perubahan yang merusak.
- Flight dimaksudkan untuk pengembang yang memasuki dunia kerangka kerja untuk pertama kalinya.
- Flight juga dapat melakukan aplikasi tingkat perusahaan, tetapi tidak memiliki sebanyak contoh dan tutorial seperti yang dimiliki Slim. Ini juga akan memerlukan lebih banyak disiplin dari pihak pengembang untuk menjaga semuanya tetap teratur dan terstruktur dengan baik.
- Flight memberikan pengembang lebih banyak kontrol atas aplikasi, sedangkan Slim dapat menyisipkan beberapa sihir di balik layar.
- Flight memiliki PdoWrapper yang sederhana yang dapat digunakan untuk berinteraksi dengan basis data Anda. Slim mengharuskan Anda menggunakan perpustakaan pihak ketiga.
- Flight memiliki plugin izin yang dapat digunakan untuk mengamankan aplikasi Anda. Slim mengharuskan Anda menggunakan perpustakaan pihak ketiga.
- Flight memiliki ORM yang disebut active-record yang dapat digunakan untuk berinteraksi dengan basis data Anda. Slim mengharuskan Anda menggunakan perpustakaan pihak ketiga.
- Flight memiliki aplikasi CLI yang disebut runway yang dapat digunakan untuk menjalankan aplikasi Anda dari command line. Slim tidak memiliki.
Learn/autoloading
Autoloading
Autoloading adalah konsep dalam PHP di mana Anda menentukan satu direktori atau beberapa direktori untuk memuat kelas. Ini jauh lebih menguntungkan daripada menggunakan require
atau include
untuk memuat kelas. Ini juga merupakan persyaratan untuk menggunakan paket Composer.
Secara default, setiap kelas Flight
dimuat otomatis untuk Anda berkat composer. Namun, jika Anda ingin memuat otomatis kelas Anda sendiri, Anda dapat menggunakan metode Flight::path()
untuk menentukan direktori yang akan memuat kelas.
Contoh Dasar
Mari kita anggap kita memiliki pohon direktori seperti berikut:
# Contoh path
/home/user/project/my-flight-project/
├── app
│ ├── cache
│ ├── config
│ ├── controllers - berisi kontroler untuk proyek ini
│ ├── translations
│ ├── UTILS - berisi kelas untuk aplikasi ini saja (ini huruf kapital semua dengan tujuan sebagai contoh nanti)
│ └── views
└── public
└── css
└── js
└── index.php
Anda mungkin telah memperhatikan bahwa ini adalah struktur file yang sama dengan situs dokumentasi ini.
Anda dapat menentukan setiap direktori untuk dimuat dari seperti ini:
/**
* public/index.php
*/
// Tambahkan path ke autoloader
Flight::path(__DIR__.'/../app/controllers/');
Flight::path(__DIR__.'/../app/utils/');
/**
* app/controllers/MyController.php
*/
// tidak ada namespace yang diperlukan
// Semua kelas yang dimuat otomatis disarankan untuk menggunakan Pascal Case (setiap kata dengan huruf kapital, tanpa spasi)
// Mulai dari 3.7.2, Anda dapat menggunakan Pascal_Snake_Case untuk nama kelas Anda dengan menjalankan Loader::setV2ClassLoading(false);
class MyController {
public function index() {
// lakukan sesuatu
}
}
Namespace
Jika Anda memiliki namespace, sebenarnya menjadi sangat mudah untuk menerapkan ini. Anda harus menggunakan metode Flight::path()
untuk menentukan direktori root (bukan document root atau folder public/
) aplikasi Anda.
/**
* public/index.php
*/
// Tambahkan path ke autoloader
Flight::path(__DIR__.'/../');
Sekarang inilah yang mungkin terlihat seperti kontroler Anda. Lihat contoh di bawah ini, tetapi perhatikan komentar untuk informasi penting.
/**
* app/controllers/MyController.php
*/
// namespace diperlukan
// namespace sama dengan struktur direktori
// namespace harus mengikuti huruf besar yang sama dengan struktur direktori
// namespace dan direktori tidak dapat memiliki garis bawah (kecuali Loader::setV2ClassLoading(false) diset)
namespace app\controllers;
// Semua kelas yang dimuat otomatis disarankan untuk menggunakan Pascal Case (setiap kata dengan huruf kapital, tanpa spasi)
// Mulai dari 3.7.2, Anda dapat menggunakan Pascal_Snake_Case untuk nama kelas Anda dengan menjalankan Loader::setV2ClassLoading(false);
class MyController {
public function index() {
// lakukan sesuatu
}
}
Dan jika Anda ingin memuat otomatis kelas di direktori utilitas Anda, Anda akan melakukan hal yang hampir sama:
/**
* app/UTILS/ArrayHelperUtil.php
*/
// namespace harus cocok dengan struktur direktori dan huruf besar (perhatikan direktori UTILS semua huruf kapital
// seperti pada pohon file di atas)
namespace app\UTILS;
class ArrayHelperUtil {
public function changeArrayCase(array $array) {
// lakukan sesuatu
}
}
Garis Bawah dalam Nama Kelas
Mulai dari 3.7.2, Anda dapat menggunakan Pascal_Snake_Case untuk nama kelas Anda dengan menjalankan Loader::setV2ClassLoading(false);
.
Ini akan memungkinkan Anda untuk menggunakan garis bawah dalam nama kelas Anda.
Ini tidak disarankan, tetapi tersedia untuk mereka yang membutuhkannya.
/**
* public/index.php
*/
// Tambahkan path ke autoloader
Flight::path(__DIR__.'/../app/controllers/');
Flight::path(__DIR__.'/../app/utils/');
Loader::setV2ClassLoading(false);
/**
* app/controllers/My_Controller.php
*/
// tidak ada namespace yang diperlukan
class My_Controller {
public function index() {
// lakukan sesuatu
}
}
Learn/troubleshooting
Pemecahan Masalah
Halaman ini akan membantu Anda memecahkan masalah umum yang mungkin Anda temui saat menggunakan Flight.
Masalah Umum
404 Tidak Ditemukan atau Perilaku Rute Tak Terduga
Jika Anda melihat kesalahan 404 Tidak Ditemukan (tetapi Anda bersumpah bahwa itu benar-benar ada dan bukan kesalahan ketik) ini sebenarnya bisa menjadi masalah dengan Anda yang mengembalikan nilai di titik akhir rute Anda alih-alih hanya mencetaknya. Alasan untuk ini adalah disengaja tetapi bisa mengganggu beberapa pengembang.
Flight::route('/hello', function(){
// Ini mungkin menyebabkan kesalahan 404 Tidak Ditemukan
return 'Hello World';
});
// Apa yang mungkin Anda inginkan
Flight::route('/hello', function(){
echo 'Hello World';
});
Alasan untuk ini adalah karena mekanisme khusus yang dibangun ke dalam router yang menangani keluaran pengembalian sebagai sinyal untuk "melanjutkan ke rute berikutnya". Anda dapat melihat perilaku ini didokumentasikan di bagian Routing.
Kelas Tidak Ditemukan (autoloading tidak bekerja)
Ada beberapa alasan mengapa ini tidak terjadi. Di bawah ini adalah beberapa contoh tetapi pastikan Anda juga memeriksa bagian autoloading.
Nama File yang Salah
Yang paling umum adalah bahwa nama kelas tidak cocok dengan nama file.
Jika Anda memiliki kelas bernama MyClass
maka file tersebut harus dinamai MyClass.php
. Jika Anda memiliki kelas bernama MyClass
dan file tersebut dinamai myclass.php
maka autoloader tidak akan dapat menemukannya.
Namespace yang Salah
Jika Anda menggunakan namespace, maka namespace harus cocok dengan struktur direktori.
// kode
// jika MyController Anda berada di direktori app/controllers dan memiliki namespace
// ini tidak akan berfungsi.
Flight::route('/hello', 'MyController->hello');
// Anda perlu memilih salah satu dari opsi ini
Flight::route('/hello', 'app\controllers\MyController->hello');
// atau jika Anda memiliki pernyataan use di atas
use app\controllers\MyController;
Flight::route('/hello', [ MyController::class, 'hello' ]);
// juga bisa ditulis
Flight::route('/hello', MyController::class.'->hello');
// juga...
Flight::route('/hello', [ 'app\controllers\MyController', 'hello' ]);
path()
tidak didefinisikan
Dalam aplikasi kerangka kerja, ini didefinisikan di dalam file config.php
, tetapi agar kelas Anda dapat ditemukan, Anda perlu memastikan bahwa metode path()
didefinisikan (kemungkinan ke root direktori Anda) sebelum Anda mencoba menggunakannya.
// Tambahkan path ke autoloader
Flight::path(__DIR__.'/../');
License
Lisensi MIT (MIT)
Hak Cipta © 2024
@mikecao, @n0nag0n
Izin diberikan di sini, tanpa biaya, kepada setiap orang yang mendapatkan salinan perangkat lunak ini dan dokumentasi terkait (disebut "Perangkat Lunak"), untuk berurusan dengan Perangkat Lunak tanpa pembatasan, termasuk tanpa batasan hak untuk menggunakan, menyalin, memodifikasi, menggabungkan, menerbitkan, mendistribusikan, sublisensikan, dan/atau menjual salinan Perangkat Lunak, dan untuk mengizinkan orang-orang yang menerima Perangkat Lunak untuk melakukannya, dengan syarat berikut:
Pemberitahuan hak cipta di atas dan pemberitahuan izin ini harus disertakan dalam semua salinan atau bagian substansial dari Perangkat Lunak.
PERANGKAT LUNAK DIBERIKAN "SEBAGAIMANA ADANYA", TANPA JAMINAN DALAM BENTUK APAPUN, TERSURAT ATAU TERSIRAT, TERMASUK NAMUN TIDAK TERBATAS PADA JAMINAN KELAYAKAN PERDAGANGAN, KECOCOKAN UNTUK TUJUAN TERTENTU DAN TIDAK MELANGGAR. DALAM HAL APA PUN PENULIS ATAU PEMEGANG HAK CIPTA TIDAK BERTANGGUNG JAWAB ATAS CLAIM, KERUSAKAN ATAU TANGGUNG JAWAB LAINNYA, BAIK DALAM TINDAKAN KONTRAK, TORT ATAU SEBALIKNYA, YANG TIMBUL DARI, DARI ATAU SEHUBUNGAN DENGAN PERANGKAT LUNAK ATAU PENGGUNAAN ATAU TRANSAKSI LAINNYA DALAM PERANGKAT LUNAK.
About
Apa itu Flight?
Flight adalah framework PHP yang cepat, sederhana, dan dapat diperluas. Ini cukup serbaguna dan dapat digunakan untuk membangun jenis aplikasi web apa pun. Ia dibangun dengan kesederhanaan dalam pikiran dan ditulis dengan cara yang mudah dipahami dan digunakan.
Flight adalah framework yang hebat untuk pemula yang baru mengenal PHP dan ingin belajar cara membangun aplikasi web. Ini juga merupakan framework yang hebat untuk pengembang berpengalaman yang ingin memiliki lebih banyak kontrol atas aplikasi web mereka. Ini dirancang untuk dengan mudah membangun API RESTful, aplikasi web sederhana, atau aplikasi web yang kompleks.
Mulai Cepat
<?php
// jika dipasang dengan composer
require 'vendor/autoload.php';
// atau jika dipasang secara manual dengan file zip
// require 'flight/Flight.php';
Flight::route('/', function() {
echo 'halo dunia!';
});
Flight::route('/json', function() {
Flight::json(['halo' => 'dunia']);
});
Flight::start();
Aplikasi Skeleton/Boilerplate
Ada aplikasi contoh yang dapat membantu Anda memulai dengan Flight Framework. Kunjungi flightphp/skeleton untuk petunjuk tentang cara memulai! Anda juga dapat mengunjungi halaman contoh untuk inspirasi tentang beberapa hal yang dapat Anda lakukan dengan Flight.
Komunitas
Kami ada di Matrix Chat bersama kami di #flight-php-framework:matrix.org.
Kontribusi
Ada dua cara Anda dapat berkontribusi pada Flight:
- Anda dapat berkontribusi pada framework inti dengan mengunjungi repositori inti.
- Anda dapat berkontribusi pada dokumentasi. Situs web dokumentasi ini dihosting di Github. Jika Anda melihat kesalahan atau ingin mengembangkan sesuatu yang lebih baik, silakan untuk memperbaikinya dan kirimkan permintaan tarik! Kami berusaha untuk terus mengikuti hal-hal tersebut, tetapi pembaruan dan terjemahan bahasa sangat diterima.
Persyaratan
Flight memerlukan PHP 7.4 atau yang lebih besar.
Catatan: PHP 7.4 didukung karena pada saat penulisan ini (2024) PHP 7.4 adalah versi default untuk beberapa distribusi Linux LTS. Memaksa migrasi ke PHP >8 dapat menyebabkan banyak masalah bagi pengguna tersebut. Framework ini juga mendukung PHP >8.
Lisensi
Flight dirilis di bawah lisensi MIT.
Awesome-plugins/php_cookie
Cookies
overclokk/cookie adalah perpustakaan sederhana untuk mengelola cookie dalam aplikasi Anda.
Instalasi
Instalasi sangat sederhana dengan composer.
composer require overclokk/cookie
Penggunaan
Penggunaan semudah mendaftarkan metode baru pada kelas Flight.
use Overclokk\Cookie\Cookie;
/*
* Set di file bootstrap atau public/index.php Anda
*/
Flight::register('cookie', Cookie::class);
/**
* ExampleController.php
*/
class ExampleController {
public function login() {
// Set sebuah cookie
// Anda ingin ini menjadi false agar Anda mendapatkan instance baru
// gunakan komentar di bawah jika Anda ingin autocomplete
/** @var \Overclokk\Cookie\Cookie $cookie */
$cookie = Flight::cookie(false);
$cookie->set(
'stay_logged_in', // nama cookie
'1', // nilai yang ingin Anda atur
86400, // jumlah detik cookie harus bertahan
'/', // jalur yang akan tersedia untuk cookie
'example.com', // domain yang akan tersedia untuk cookie
true, // cookie hanya akan ditransmisikan melalui koneksi HTTPS yang aman
true // cookie hanya akan tersedia melalui protokol HTTP
);
// opsional, jika Anda ingin mempertahankan nilai default
// dan memiliki cara cepat untuk mengatur cookie untuk waktu yang lama
$cookie->forever('stay_logged_in', '1');
}
public function home() {
// Periksa apakah Anda memiliki cookie
if (Flight::cookie()->has('stay_logged_in')) {
// tempatkan mereka di area dasbor misalnya.
Flight::redirect('/dashboard');
}
}
}
Awesome-plugins/php_encryption
Enkripsi PHP
defuse/php-encryption adalah perpustakaan yang dapat digunakan untuk mengenkripsi dan mendekripsi data. Memulai dan menjalankan cukup sederhana untuk mulai mengenkripsi dan mendekripsi data. Mereka memiliki tutorial yang sangat membantu menjelaskan dasar-dasar cara menggunakan perpustakaan serta implikasi keamanan penting terkait enkripsi.
Instalasi
Instalasi sangat sederhana dengan composer.
composer require defuse/php-encryption
Pengaturan
Kemudian Anda perlu menghasilkan kunci enkripsi.
vendor/bin/generate-defuse-key
Ini akan menghasilkan kunci yang perlu Anda simpan dengan aman. Anda bisa menyimpan kunci di file app/config/config.php
Anda di array di bagian bawah file. Meskipun itu bukan tempat yang sempurna, paling tidak itu adalah sesuatu.
Penggunaan
Sekarang Anda memiliki perpustakaan dan kunci enkripsi, Anda dapat mulai mengenkripsi dan mendekripsi data.
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;
/*
* Tetapkan di file bootstrap atau public/index.php Anda
*/
// Metode enkripsi
Flight::map('encrypt', function($raw_data) {
$encryption_key = /* $config['encryption_key'] atau file_get_contents tempat Anda meletakkan kunci */;
return Crypto::encrypt($raw_data, Key::loadFromAsciiSafeString($encryption_key));
});
// Metode dekripsi
Flight::map('decrypt', function($encrypted_data) {
$encryption_key = /* $config['encryption_key'] atau file_get_contents tempat Anda meletakkan kunci */;
try {
$raw_data = Crypto::decrypt($encrypted_data, Key::loadFromAsciiSafeString($encryption_key));
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
// Sebuah serangan! Entah kunci yang salah dimuat, atau ciphertext telah
// berubah sejak dibuat -- baik rusak di database atau
// sengaja dimodifikasi oleh Eve yang mencoba melakukan serangan.
// ... tangani kasus ini dengan cara yang sesuai untuk aplikasi Anda ...
}
return $raw_data;
});
Flight::route('/encrypt', function() {
$encrypted_data = Flight::encrypt('Ini adalah rahasia');
echo $encrypted_data;
});
Flight::route('/decrypt', function() {
$encrypted_data = '...'; // Ambil data terenkripsi dari suatu tempat
$decrypted_data = Flight::decrypt($encrypted_data);
echo $decrypted_data;
});
Awesome-plugins/php_file_cache
Wruczek/PHP-File-Cache
Kelas caching in-file PHP yang ringan, sederhana, dan mandiri
Keuntungan
- Ringan, mandiri, dan sederhana
- Semua kode dalam satu file - tidak ada driver yang tidak berguna.
- Aman - setiap file cache yang dihasilkan memiliki header php dengan die, menjadikan akses langsung tidak mungkin meskipun seseorang mengetahui jalannya dan server Anda tidak dikonfigurasi dengan benar
- Didokumentasikan dengan baik dan diuji
- Menangani concurrency dengan benar melalui flock
- Mendukung PHP 5.4.0 - 7.1+
- Gratis di bawah lisensi MIT
Klik di sini untuk melihat kode.
Instalasi
Instal melalui composer:
composer require wruczek/php-file-cache
Penggunaan
Penggunaan cukup sederhana.
use Wruczek\PhpFileCache\PhpFileCache;
$app = Flight::app();
// Anda mengirimkan direktori tempat cache akan disimpan ke dalam konstruktor
$app->register('cache', PhpFileCache::class, [ __DIR__ . '/../cache/' ], function(PhpFileCache $cache) {
// Ini memastikan bahwa cache hanya digunakan saat dalam mode produksi
// ENVIRONMENT adalah sebuah konstanta yang diatur dalam file bootstrap Anda atau di tempat lain dalam aplikasi Anda
$cache->setDevMode(ENVIRONMENT === 'development');
});
Kemudian Anda dapat menggunakannya dalam kode Anda seperti ini:
// Ambil instance cache
$cache = Flight::cache();
$data = $cache->refreshIfExpired('simple-cache-test', function () {
return date("H:i:s"); // mengembalikan data untuk dicache
}, 10); // 10 detik
// atau
$data = $cache->retrieve('simple-cache-test');
if(empty($data)) {
$data = date("H:i:s");
$cache->store('simple-cache-test', $data, 10); // 10 detik
}
Dokumentasi
Kunjungi https://github.com/Wruczek/PHP-File-Cache untuk dokumentasi lengkap dan pastikan Anda melihat folder contoh.
Awesome-plugins/permissions
FlightPHP/Permissions
Ini adalah modul izin yang dapat digunakan dalam proyek Anda jika Anda memiliki beberapa peran di aplikasi Anda dan setiap peran memiliki sedikit fungsi yang berbeda. Modul ini memungkinkan Anda untuk mendefinisikan izin untuk setiap peran dan kemudian memeriksa apakah pengguna saat ini memiliki izin untuk mengakses halaman tertentu atau melakukan tindakan tertentu.
Klik di sini untuk repositori di GitHub.
Instalasi
Jalankan composer require flightphp/permissions
dan Anda sudah siap!
Penggunaan
Pertama, Anda perlu mengatur izin Anda, lalu Anda memberi tahu aplikasi Anda apa arti izin tersebut. Pada akhirnya, Anda akan memeriksa izin Anda dengan $Permissions->has()
, ->can()
, atau is()
. has()
dan can()
memiliki fungsionalitas yang sama, tetapi dinamai berbeda untuk membuat kode Anda lebih mudah dibaca.
Contoh Dasar
Mari kita anggap Anda memiliki fitur dalam aplikasi Anda yang memeriksa apakah seorang pengguna sudah masuk. Anda dapat membuat objek izin seperti ini:
// index.php
require 'vendor/autoload.php';
// beberapa kode
// lalu Anda mungkin memiliki sesuatu yang memberi tahu Anda siapa peran saat ini dari orang tersebut
// kemungkinan Anda memiliki sesuatu di mana Anda mengambil peran saat ini
// dari variabel sesi yang mendefinisikan ini
// setelah seseorang masuk, jika tidak, mereka akan memiliki peran 'tamu' atau 'publik'.
$current_role = 'admin';
// mengatur izin
$permission = new \flight\Permission($current_role);
$permission->defineRule('loggedIn', function($current_role) {
return $current_role !== 'guest';
});
// Anda mungkin ingin menyimpan objek ini di Flight di suatu tempat
Flight::set('permission', $permission);
Kemudian di dalam controller di suatu tempat, Anda mungkin memiliki sesuatu seperti ini.
<?php
// beberapa controller
class SomeController {
public function someAction() {
$permission = Flight::get('permission');
if ($permission->has('loggedIn')) {
// lakukan sesuatu
} else {
// lakukan sesuatu yang lain
}
}
}
Anda juga dapat menggunakan ini untuk melacak apakah mereka memiliki izin untuk melakukan sesuatu dalam aplikasi Anda. Sebagai contoh, jika Anda memiliki cara bagi pengguna untuk berinteraksi dengan posting di perangkat lunak Anda, Anda dapat memeriksa apakah mereka memiliki izin untuk melakukan tindakan tertentu.
$current_role = 'admin';
// mengatur izin
$permission = new \flight\Permission($current_role);
$permission->defineRule('post', function($current_role) {
if($current_role === 'admin') {
$permissions = ['create', 'read', 'update', 'delete'];
} else if($current_role === 'editor') {
$permissions = ['create', 'read', 'update'];
} else if($current_role === 'author') {
$permissions = ['create', 'read'];
} else if($current_role === 'contributor') {
$permissions = ['create'];
} else {
$permissions = [];
}
return $permissions;
});
Flight::set('permission', $permission);
Kemudian di dalam controller di suatu tempat...
class PostController {
public function create() {
$permission = Flight::get('permission');
if ($permission->can('post.create')) {
// lakukan sesuatu
} else {
// lakukan sesuatu yang lain
}
}
}
Menginjeksi ketergantungan
Anda dapat menginjeksi ketergantungan ke dalam closure yang mendefinisikan izin. Ini berguna jika Anda memiliki semacam toggle, id, atau titik data lain yang ingin Anda periksa. Hal ini juga berlaku untuk panggilan jenis Class->Method, kecuali Anda mendefinisikan argumen dalam metode tersebut.
Closure
$Permission->defineRule('order', function(string $current_role, MyDependency $MyDependency = null) {
// ... kode
});
// di file controller Anda
public function createOrder() {
$MyDependency = Flight::myDependency();
$permission = Flight::get('permission');
if ($permission->can('order.create', $MyDependency)) {
// lakukan sesuatu
} else {
// lakukan sesuatu yang lain
}
}
Kelas
namespace MyApp;
class Permissions {
public function order(string $current_role, MyDependency $MyDependency = null) {
// ... kode
}
}
Pintasan untuk mengatur izin dengan kelas
Anda juga dapat menggunakan kelas untuk mendefinisikan izin Anda. Ini berguna jika Anda memiliki banyak izin dan Anda ingin menjaga kode Anda tetap bersih. Anda bisa melakukan sesuatu seperti ini:
<?php
// kode bootstrap
$Permissions = new \flight\Permission($current_role);
$Permissions->defineRule('order', 'MyApp\Permissions->order');
// myapp/Permissions.php
namespace MyApp;
class Permissions {
public function order(string $current_role, int $user_id) {
// Mengasumsikan Anda telah mengatur ini sebelumnya
/** @var \flight\database\PdoWrapper $db */
$db = Flight::db();
$allowed_permissions = [ 'read' ]; // semua orang dapat melihat sebuah pesanan
if($current_role === 'manager') {
$allowed_permissions[] = 'create'; // manajer dapat membuat pesanan
}
$some_special_toggle_from_db = $db->fetchField('SELECT some_special_toggle FROM settings WHERE id = ?', [ $user_id ]);
if($some_special_toggle_from_db) {
$allowed_permissions[] = 'update'; // jika pengguna memiliki toggle khusus, mereka dapat memperbarui pesanan
}
if($current_role === 'admin') {
$allowed_permissions[] = 'delete'; // admin dapat menghapus pesanan
}
return $allowed_permissions;
}
}
Bagian yang keren adalah bahwa ada juga pintasan yang dapat Anda gunakan (yang juga dapat dicache!!!) di mana Anda cukup memberi tahu kelas izin untuk memetakan semua metode dalam sebuah kelas ke dalam izin. Jadi jika Anda memiliki metode bernama order()
dan metode bernama company()
, ini akan secara otomatis dipetakan sehingga Anda cukup menjalankan $Permissions->has('order.read')
atau $Permissions->has('company.read')
dan itu akan berhasil. Mendefinisikan ini sangat sulit, jadi ikutlah bersama saya di sini. Anda hanya perlu melakukan ini:
Buat kelas izin yang ingin Anda kelompokkan bersama.
class MyPermissions {
public function order(string $current_role, int $order_id = 0): array {
// kode untuk menentukan izin
return $permissions_array;
}
public function company(string $current_role, int $company_id): array {
// kode untuk menentukan izin
return $permissions_array;
}
}
Kemudian buat izin tersebut dapat ditemukan menggunakan pustaka ini.
$Permissions = new \flight\Permission($current_role);
$Permissions->defineRulesFromClassMethods(MyApp\Permissions::class);
Flight::set('permissions', $Permissions);
Akhirnya, panggil izin di basis kode Anda untuk memeriksa apakah pengguna diizinkan untuk melakukan izin tertentu.
class SomeController {
public function createOrder() {
if(Flight::get('permissions')->can('order.create') === false) {
die('Anda tidak bisa membuat sebuah pesanan. Maaf!');
}
}
}
Cache
Untuk mengaktifkan caching, lihat pustaka sederhana wruczak/phpfilecache. Contoh untuk mengaktifkannya ada di bawah ini.
// $app ini bisa menjadi bagian dari kode Anda, atau
// Anda bisa langsung meneruskan null dan itu akan
// mengambil dari Flight::app() di dalam konstruktor
$app = Flight::app();
// Untuk saat ini, ini menerima sebagai cache file. Lainnya dapat dengan mudah
// ditambahkan di masa depan.
$Cache = new Wruczek\PhpFileCache\PhpFileCache;
$Permissions = new \flight\Permission($current_role, $app, $Cache);
$Permissions->defineRulesFromClassMethods(MyApp\Permissions::class, 3600); // 3600 adalah berapa detik untuk menyimpan cache ini. Biarkan ini kosong untuk tidak menggunakan caching
Dan Anda sudah siap!
Awesome-plugins/pdo_wrapper
Kelas Pembantu PDO PdoWrapper
Flight hadir dengan kelas pembantu untuk PDO. Kelas ini memungkinkan Anda untuk dengan mudah melakukan kueri ke basis data Anda dengan semua persiapan/eksekusi/fetchAll() yang membingungkan. Ini sangat menyederhanakan cara Anda dapat melakukan kueri ke basis data Anda. Setiap hasil baris dikembalikan sebagai kelas Koleksi Flight yang memungkinkan Anda mengakses data Anda melalui sintaks array atau sintaks objek.
Mendaftar Kelas Pembantu PDO
// Daftarkan kelas pembantu PDO
Flight::register('db', \flight\database\PdoWrapper::class, ['mysql:host=localhost;dbname=cool_db_name', 'user', 'pass', [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\'',
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
]);
Penggunaan
Objek ini memperluas PDO sehingga semua metode PDO normal tersedia. Metode berikut ditambahkan untuk mempermudah kueri ke basis data:
runQuery(string $sql, array $params = []): PDOStatement
Gunakan ini untuk INSERTS, UPDATES, atau jika Anda berencana menggunakan SELECT dalam loop while
$db = Flight::db();
$statement = $db->runQuery("SELECT * FROM table WHERE something = ?", [ $something ]);
while($row = $statement->fetch()) {
// ...
}
// Atau menulis ke basis data
$db->runQuery("INSERT INTO table (name) VALUES (?)", [ $name ]);
$db->runQuery("UPDATE table SET name = ? WHERE id = ?", [ $name, $id ]);
fetchField(string $sql, array $params = []): mixed
Mengambil field pertama dari kueri
$db = Flight::db();
$count = $db->fetchField("SELECT COUNT(*) FROM table WHERE something = ?", [ $something ]);
fetchRow(string $sql, array $params = []): array
Mengambil satu baris dari kueri
$db = Flight::db();
$row = $db->fetchRow("SELECT id, name FROM table WHERE id = ?", [ $id ]);
echo $row['name'];
// atau
echo $row->name;
fetchAll(string $sql, array $params = []): array
Mengambil semua baris dari kueri
$db = Flight::db();
$rows = $db->fetchAll("SELECT id, name FROM table WHERE something = ?", [ $something ]);
foreach($rows as $row) {
echo $row['name'];
// atau
echo $row->name;
}
Catatan dengan sintaks IN()
Ini juga memiliki pembungkus yang berguna untuk pernyataan IN()
. Anda cukup memasukkan tanda tanya tunggal sebagai placeholder untuk IN()
dan kemudian array nilai. Berikut adalah contoh seperti apa itu:
$db = Flight::db();
$name = 'Bob';
$company_ids = [1,2,3,4,5];
$rows = $db->fetchAll("SELECT id, name FROM table WHERE name = ? AND company_id IN (?)", [ $name, $company_ids ]);
Contoh Lengkap
// Contoh rute dan cara Anda akan menggunakan pembungkus ini
Flight::route('/users', function () {
// Dapatkan semua pengguna
$users = Flight::db()->fetchAll('SELECT * FROM users');
// Streaming semua pengguna
$statement = Flight::db()->runQuery('SELECT * FROM users');
while ($user = $statement->fetch()) {
echo $user['name'];
// atau echo $user->name;
}
// Dapatkan satu pengguna
$user = Flight::db()->fetchRow('SELECT * FROM users WHERE id = ?', [123]);
// Dapatkan satu nilai
$count = Flight::db()->fetchField('SELECT COUNT(*) FROM users');
// Sintaks IN() khusus untuk membantu (pastikan IN ditulis dengan huruf kapital)
$users = Flight::db()->fetchAll('SELECT * FROM users WHERE id IN (?)', [[1,2,3,4,5]]);
// Anda juga dapat melakukan ini
$users = Flight::db()->fetchAll('SELECT * FROM users WHERE id IN (?)', [ '1,2,3,4,5']);
// Memasukkan pengguna baru
Flight::db()->runQuery("INSERT INTO users (name, email) VALUES (?, ?)", ['Bob', 'bob@example.com']);
$insert_id = Flight::db()->lastInsertId();
// Memperbarui pengguna
Flight::db()->runQuery("UPDATE users SET name = ? WHERE id = ?", ['Bob', 123]);
// Menghapus pengguna
Flight::db()->runQuery("DELETE FROM users WHERE id = ?", [123]);
// Dapatkan jumlah baris yang terpengaruh
$statement = Flight::db()->runQuery("UPDATE users SET name = ? WHERE name = ?", ['Bob', 'Sally']);
$affected_rows = $statement->rowCount();
});
Awesome-plugins/session
Ghostff/Session
Manajer Sesi PHP (non-blocking, flash, segmen, enkripsi sesi). Menggunakan PHP open_ssl untuk enkripsi/dekripsi data sesi secara opsional. Mendukung File, MySQL, Redis, dan Memcached.
Klik di sini untuk melihat kodenya.
Instalasi
Install menggunakan composer.
composer require ghostff/session
Konfigurasi Dasar
Anda tidak perlu meneruskan apapun untuk menggunakan pengaturan default dengan sesi Anda. Anda dapat membaca lebih banyak tentang pengaturan di Github Readme.
use Ghostff\Session\Session;
require 'vendor/autoload.php';
$app = Flight::app();
$app->register('session', Session::class);
// satu hal yang perlu diingat adalah bahwa Anda harus mengkomit sesi Anda pada setiap pemuatan halaman
// atau Anda perlu menjalankan auto_commit dalam konfigurasi Anda.
Contoh Sederhana
Berikut adalah contoh sederhana tentang bagaimana Anda mungkin menggunakan ini.
Flight::route('POST /login', function() {
$session = Flight::session();
// lakukan logika login Anda di sini
// validasi kata sandi, dll.
// jika login berhasil
$session->set('is_logged_in', true);
$session->set('user', $user);
// setiap kali Anda menulis ke sesi, Anda harus mengkomitnya secara sengaja.
$session->commit();
});
// Pemeriksaan ini bisa ada dalam logika halaman terbatas, atau dibungkus dengan middleware.
Flight::route('/some-restricted-page', function() {
$session = Flight::session();
if(!$session->get('is_logged_in')) {
Flight::redirect('/login');
}
// lakukan logika halaman terbatas Anda di sini
});
// versi middleware
Flight::route('/some-restricted-page', function() {
// logika halaman reguler
})->addMiddleware(function() {
$session = Flight::session();
if(!$session->get('is_logged_in')) {
Flight::redirect('/login');
}
});
Contoh yang Lebih Kompleks
Berikut adalah contoh yang lebih kompleks tentang bagaimana Anda mungkin menggunakan ini.
use Ghostff\Session\Session;
require 'vendor/autoload.php';
$app = Flight::app();
// atur path kustom untuk file konfigurasi sesi Anda dan berikan string acak untuk id sesi
$app->register('session', Session::class, [ 'path/to/session_config.php', bin2hex(random_bytes(32)) ], function(Session $session) {
// atau Anda dapat secara manual menimpa opsi konfigurasi
$session->updateConfiguration([
// jika Anda ingin menyimpan data sesi Anda dalam database (baik jika Anda ingin sesuatu seperti, "keluarkan saya dari semua perangkat" fungsionalitas)
Session::CONFIG_DRIVER => Ghostff\Session\Drivers\MySql::class,
Session::CONFIG_ENCRYPT_DATA => true,
Session::CONFIG_SALT_KEY => hash('sha256', 'my-super-S3CR3T-salt'), // silakan ganti ini menjadi sesuatu yang lain
Session::CONFIG_AUTO_COMMIT => true, // hanya lakukan ini jika memerlukannya dan/atau sulit untuk mengkomit sesi Anda.
// tambahan Anda bisa melakukan Flight::after('start', function() { Flight::session()->commit(); });
Session::CONFIG_MYSQL_DS => [
'driver' => 'mysql', # Driver database untuk dns PDO eg(mysql:host=...;dbname=...)
'host' => '127.0.0.1', # Host database
'db_name' => 'my_app_database', # Nama database
'db_table' => 'sessions', # Tabel database
'db_user' => 'root', # Nama pengguna database
'db_pass' => '', # Kata sandi database
'persistent_conn'=> false, # Hindari biaya overhead untuk membuat koneksi baru setiap kali skrip perlu berbicara ke database, yang mengakibatkan aplikasi web yang lebih cepat. TEMUKAN BELAKANGNYA SENDIRI
]
]);
}
);
Bantuan! Data Sesi Saya Tidak Persisten!
Apakah Anda mengatur data sesi Anda dan tidak persisten antara permintaan? Anda mungkin lupa untuk mengkomit data sesi Anda. Anda dapat melakukan ini dengan memanggil $session->commit()
setelah Anda mengatur data sesi Anda.
Flight::route('POST /login', function() {
$session = Flight::session();
// lakukan logika login Anda di sini
// validasi kata sandi, dll.
// jika login berhasil
$session->set('is_logged_in', true);
$session->set('user', $user);
// setiap kali Anda menulis ke sesi, Anda harus mengkomitnya secara sengaja.
$session->commit();
});
Cara lain untuk mengatasi ini adalah ketika Anda mengatur layanan sesi Anda, Anda harus mengatur auto_commit
menjadi true
dalam konfigurasi Anda. Ini akan secara otomatis mengkomit data sesi Anda setelah setiap permintaan.
$app->register('session', Session::class, [ 'path/to/session_config.php', bin2hex(random_bytes(32)) ], function(Session $session) {
$session->updateConfiguration([
Session::CONFIG_AUTO_COMMIT => true,
]);
}
);
Selain itu, Anda dapat melakukan Flight::after('start', function() { Flight::session()->commit(); });
untuk mengkomit data sesi Anda setelah setiap permintaan.
Dokumentasi
Kunjungi Github Readme untuk dokumentasi lengkap. Opsi konfigurasi didokumentasikan dengan baik dalam default_config.php file itu sendiri. Kodenya mudah untuk dipahami jika Anda ingin meneliti paket ini sendiri.
Awesome-plugins/runway
Jalur
Jalur adalah aplikasi CLI yang membantu Anda mengelola aplikasi Flight Anda. Ini dapat menghasilkan pengontrol, menampilkan semua rute, dan banyak lagi. Ini didasarkan pada pustaka adhocore/php-cli yang sangat baik.
Klik di sini untuk melihat kodenya.
Instalasi
Instal dengan composer.
composer require flightphp/runway
Konfigurasi Dasar
Kali pertama Anda menjalankan Jalur, itu akan memandu Anda melalui proses pengaturan dan membuat file konfigurasi .runway.json
di akar proyek Anda. File ini akan berisi beberapa konfigurasi yang diperlukan agar Jalur berfungsi dengan baik.
Penggunaan
Jalur memiliki sejumlah perintah yang dapat Anda gunakan untuk mengelola aplikasi Flight Anda. Ada dua cara mudah untuk menggunakan Jalur.
- Jika Anda menggunakan proyek tulang, Anda dapat menjalankan
php runway [command]
dari akar proyek Anda. - Jika Anda menggunakan Jalur sebagai paket yang diinstal melalui composer, Anda dapat menjalankan
vendor/bin/runway [command]
dari akar proyek Anda.
Untuk setiap perintah, Anda dapat melewatkan bendera --help
untuk mendapatkan informasi lebih lanjut tentang cara menggunakan perintah tersebut.
php runway routes --help
Berikut adalah beberapa contoh:
Menghasilkan Pengontrol
Berdasarkan konfigurasi dalam file .runway.json
Anda, lokasi default akan menghasilkan pengontrol untuk Anda di direktori app/controllers/
.
php runway make:controller MyController
Menghasilkan Model Rekaman Aktif
Berdasarkan konfigurasi dalam file .runway.json
Anda, lokasi default akan menghasilkan pengontrol untuk Anda di direktori app/records/
.
php runway make:record users
Jika misalnya Anda memiliki tabel users
dengan skema berikut: id
, name
, email
, created_at
, updated_at
, sebuah file yang mirip dengan yang berikut akan dibuat di file app/records/UserRecord.php
:
<?php
declare(strict_types=1);
namespace app\records;
/**
* Kelas ActiveRecord untuk tabel users.
* @link https://docs.flightphp.com/awesome-plugins/active-record
*
* @property int $id
* @property string $name
* @property string $email
* @property string $created_at
* @property string $updated_at
* // Anda juga bisa menambahkan hubungan di sini setelah Anda mendefinisikannya di array $relations
* @property CompanyRecord $company Contoh hubungan
*/
class UserRecord extends \flight\ActiveRecord
{
/**
* @var array $relations Tetapkan hubungan untuk model
* https://docs.flightphp.com/awesome-plugins/active-record#relationships
*/
protected array $relations = [];
/**
* Konstruktor
* @param mixed $databaseConnection Koneksi ke database
*/
public function __construct($databaseConnection)
{
parent::__construct($databaseConnection, 'users');
}
}
Tampilkan Semua Rute
Ini akan menampilkan semua rute yang saat ini terdaftar dengan Flight.
php runway routes
Jika Anda ingin hanya melihat rute tertentu, Anda dapat melewatkan bendera untuk menyaring rute.
# Tampilkan hanya rute GET
php runway routes --get
# Tampilkan hanya rute POST
php runway routes --post
# dll.
Menyesuaikan Jalur
Jika Anda membuat paket untuk Flight, atau ingin menambahkan perintah kustom Anda sendiri ke dalam proyek Anda, Anda dapat melakukannya dengan membuat direktori src/commands/
, flight/commands/
, app/commands/
, atau commands/
untuk proyek/paket Anda. Jika Anda memerlukan penyesuaian lebih lanjut, lihat bagian di bawah tentang Konfigurasi.
Untuk membuat perintah, Anda cukup memperluas kelas AbstractBaseCommand
, dan menerapkan setidaknya metode __construct
dan metode execute
.
<?php
declare(strict_types=1);
namespace flight\commands;
class ExampleCommand extends AbstractBaseCommand
{
/**
* Konstruktor
*
* @param array<string,mixed> $config Konfigurasi JSON dari .runway-config.json
*/
public function __construct(array $config)
{
parent::__construct('make:example', 'Buat contoh untuk dokumentasi', $config);
$this->argument('<funny-gif>', 'Nama gif lucu');
}
/**
* Menjalankan fungsi
*
* @return void
*/
public function execute(string $controller)
{
$io = $this->app()->io();
$io->info('Membuat contoh...');
// Lakukan sesuatu di sini
$io->ok('Contoh dibuat!');
}
}
Lihat adhocore/php-cli Documentation untuk informasi lebih lanjut tentang cara membangun perintah kustom Anda sendiri ke dalam aplikasi Flight Anda!
Konfigurasi
Jika Anda perlu menyesuaikan konfigurasi untuk Jalur, Anda dapat membuat file .runway-config.json
di akar proyek Anda. Di bawah ini adalah beberapa konfigurasi tambahan yang dapat Anda tetapkan:
{
// Ini adalah tempat direktori aplikasi Anda berada
"app_root": "app/",
// Ini adalah direktori tempat file indeks akar Anda berada
"index_root": "public/",
// Ini adalah jalur ke akar proyek lainnya
"root_paths": [
"/home/user/different-project",
"/var/www/another-project"
],
// Jalur dasar kemungkinan besar tidak perlu dikonfigurasi, tapi ada di sini jika Anda menginginkannya
"base_paths": {
"/includes/libs/vendor", // jika Anda memiliki jalur yang sangat unik untuk direktori vendor Anda atau sesuatu
},
// Jalur akhir adalah lokasi dalam proyek untuk mencari file perintah
"final_paths": {
"src/diff-path/commands",
"app/module/admin/commands",
},
// Jika Anda ingin hanya menambahkan jalur lengkap, silakan saja (absolut atau relatif terhadap akar proyek)
"paths": [
"/home/user/different-project/src/diff-path/commands",
"/var/www/another-project/app/module/admin/commands",
"app/my-unique-commands"
]
}
Awesome-plugins/tracy_extensions
Tracy Flight Panel Extensions
Ini adalah serangkaian ekstensi untuk membuat kerja dengan Flight sedikit lebih kaya.
- Flight - Analisis semua variabel Flight.
- Database - Analisis semua kueri yang telah dijalankan di halaman (jika Anda benar-benar memulai koneksi database)
- Request - Analisis semua variabel
$_SERVER
dan periksa semua payload global ($_GET
,$_POST
,$_FILES
) - Session - Analisis semua variabel
$_SESSION
jika sesi aktif.
Ini adalah Panel
Dan setiap panel menampilkan informasi yang sangat berguna tentang aplikasi Anda!
Klik di sini untuk melihat kode.
Instalasi
Jalankan composer require flightphp/tracy-extensions --dev
dan Anda sudah siap!
Konfigurasi
Ada sangat sedikit konfigurasi yang perlu Anda lakukan untuk memulai ini. Anda perlu memulai debugger Tracy sebelum menggunakan ini https://tracy.nette.org/en/guide:
<?php
use Tracy\Debugger;
use flight\debug\tracy\TracyExtensionLoader;
// kode bootstrap
require __DIR__ . '/vendor/autoload.php';
Debugger::enable();
// Anda mungkin perlu menentukan lingkungan Anda dengan Debugger::enable(Debugger::DEVELOPMENT)
// jika Anda menggunakan koneksi database dalam aplikasi Anda, ada
// pembungkus PDO yang diperlukan untuk digunakan HANYA DI PENGEMBANGAN (bukan produksi, tolong!)
// Ini memiliki parameter yang sama dengan koneksi PDO biasa
$pdo = new PdoQueryCapture('sqlite:test.db', 'user', 'pass');
// atau jika Anda melampirkan ini ke framework Flight
Flight::register('db', PdoQueryCapture::class, ['sqlite:test.db', 'user', 'pass']);
// sekarang setiap kali Anda melakukan kueri, akan menangkap waktu, kueri, dan parameter
// Ini menghubungkan titik-titik
if(Debugger::$showBar === true) {
// Ini perlu false atau Tracy tidak bisa benar-benar merender :(
Flight::set('flight.content_length', false);
new TracyExtensionLoader(Flight::app());
}
// lebih banyak kode
Flight::start();
Konfigurasi Tambahan
Data Sesi
Jika Anda memiliki pengendali sesi kustom (seperti ghostff/session), Anda dapat meneruskan array data sesi apa pun ke Tracy dan secara otomatis akan mengeluarkannya untuk Anda. Anda mengirimkannya dengan kunci session_data
di parameter kedua konstruktor TracyExtensionLoader
.
use Ghostff\Session\Session;
require 'vendor/autoload.php';
$app = Flight::app();
$app->register('session', Session::class);
if(Debugger::$showBar === true) {
// Ini perlu false atau Tracy tidak bisa benar-benar merender :(
Flight::set('flight.content_length', false);
new TracyExtensionLoader(Flight::app(), [ 'session_data' => Flight::session()->getAll() ]);
}
// rute dan hal-hal lain...
Flight::start();
Latte
Jika Anda telah menginstal Latte di proyek Anda, Anda dapat menggunakan panel Latte untuk menganalisis template Anda. Anda dapat meneruskan instance Latte ke konstruktor TracyExtensionLoader
dengan kunci latte
di parameter kedua.
use Latte\Engine;
require 'vendor/autoload.php';
$app = Flight::app();
$app->register('latte', Engine::class, [], function($latte) {
$latte->setTempDirectory(__DIR__ . '/temp');
// di sinilah Anda menambahkan Panel Latte ke Tracy
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
});
if(Debugger::$showBar === true) {
// Ini perlu false atau Tracy tidak bisa benar-benar merender :(
Flight::set('flight.content_length', false);
new TracyExtensionLoader(Flight::app());
}
Awesome-plugins/tracy
Tracy
Tracy adalah penangan kesalahan yang luar biasa yang dapat digunakan dengan Flight. Ia memiliki sejumlah panel yang dapat membantu Anda dalam mendebug aplikasi Anda. Ini juga sangat mudah untuk diperluas dan menambahkan panel Anda sendiri. Tim Flight telah membuat beberapa panel khusus untuk proyek Flight dengan plugin flightphp/tracy-extensions.
Instalasi
Instal dengan composer. Dan Anda akan ingin menginstal ini tanpa versi dev karena Tracy dilengkapi dengan komponen penanganan kesalahan produksi.
composer require tracy/tracy
Konfigurasi Dasar
Ada beberapa opsi konfigurasi dasar untuk memulai. Anda dapat membaca lebih lanjut tentang mereka di Dokumentasi Tracy.
require 'vendor/autoload.php';
use Tracy\Debugger;
// Mengaktifkan Tracy
Debugger::enable();
// Debugger::enable(Debugger::DEVELOPMENT) // kadang-kadang Anda harus eksplisit (juga Debugger::PRODUCTION)
// Debugger::enable('23.75.345.200'); // Anda juga dapat menyediakan array alamat IP
// Di sinilah kesalahan dan pengecualian akan dicatat. Pastikan direktori ini ada dan dapat ditulisi.
Debugger::$logDirectory = __DIR__ . '/../log/';
Debugger::$strictMode = true; // tampilkan semua kesalahan
// Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // semua kesalahan kecuali pemberitahuan kadaluarsa
if (Debugger::$showBar) {
$app->set('flight.content_length', false); // jika bilah Debugger terlihat, maka panjang konten tidak dapat diatur oleh Flight
// Ini khusus untuk Ekstensi Tracy untuk Flight jika Anda telah menyertakannya
// jika tidak, silakan komentari ini.
new TracyExtensionLoader($app);
}
Tips Berguna
Saat Anda mendebug kode Anda, ada beberapa fungsi yang sangat berguna untuk mengeluarkan data untuk Anda.
bdump($var)
- Ini akan mencetak variabel ke Tracy Bar di panel terpisah.dumpe($var)
- Ini akan mencetak variabel dan kemudian mati segera.
Awesome-plugins/active_record
Flight Active Record
Sebuah rekaman aktif adalah pemetaan entitas basis data ke dalam objek PHP. Secara sederhana, jika Anda memiliki tabel pengguna di basis data Anda, Anda dapat "mentranslasi" sebuah baris di tabel tersebut menjadi kelas User
dan objek $user
dalam basis kode Anda. Lihat contoh dasar.
Klik di sini untuk repositori di GitHub.
Contoh Dasar
Mari kita asumsikan Anda memiliki tabel berikut:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
password TEXT
);
Sekarang Anda dapat menyiapkan kelas baru untuk merepresentasikan tabel ini:
/**
* Kelas ActiveRecord biasanya tunggal
*
* Sangat direkomendasikan untuk menambahkan properti dari tabel sebagai komentar di sini
*
* @property int $id
* @property string $name
* @property string $password
*/
class User extends flight\ActiveRecord {
public function __construct($database_connection)
{
// Anda dapat menetapkannya dengan cara ini
parent::__construct($database_connection, 'users');
// atau dengan cara ini
parent::__construct($database_connection, null, [ 'table' => 'users']);
}
}
Sekarang saksikan keajaiban terjadi!
// untuk sqlite
$database_connection = new PDO('sqlite:test.db'); // ini hanya untuk contoh, Anda mungkin akan menggunakan koneksi basis data yang nyata
// untuk mysql
$database_connection = new PDO('mysql:host=localhost;dbname=test_db&charset=utf8bm4', 'username', 'password');
// atau mysqli
$database_connection = new mysqli('localhost', 'username', 'password', 'test_db');
// atau mysqli dengan penciptaan non-objek
$database_connection = mysqli_connect('localhost', 'username', 'password', 'test_db');
$user = new User($database_connection);
$user->name = 'Bobby Tables';
$user->password = password_hash('some cool password');
$user->insert();
// atau $user->save();
echo $user->id; // 1
$user->name = 'Joseph Mamma';
$user->password = password_hash('some cool password again!!!');
$user->insert();
// tidak bisa menggunakan $user->save() di sini atau akan berpikir ini adalah pembaruan!
echo $user->id; // 2
Dan begitu mudahnya untuk menambahkan pengguna baru! Sekarang ada baris pengguna di basis data, bagaimana cara mengambilnya keluar?
$user->find(1); // cari id = 1 di basis data dan kembalikan.
echo $user->name; // 'Bobby Tables'
Dan bagaimana jika Anda ingin menemukan semua pengguna?
$users = $user->findAll();
Bagaimana dengan kondisi tertentu?
$users = $user->like('name', '%mamma%')->findAll();
Lihat betapa menyenangkannya ini? Mari kita instal dan mulai!
Instalasi
Cukup instal dengan Composer
composer require flightphp/active-record
Penggunaan
Ini bisa digunakan sebagai pustaka mandiri atau dengan Flight PHP Framework. Sepenuhnya terserah Anda.
Mandiri
Pastikan Anda melewatkan koneksi PDO ke konstruktor.
$pdo_connection = new PDO('sqlite:test.db'); // ini hanya untuk contoh, Anda mungkin akan menggunakan koneksi basis data yang nyata
$User = new User($pdo_connection);
Tidak ingin selalu menetapkan koneksi basis data Anda di konstruktor? Lihat Manajemen Koneksi Basis Data untuk ide lainnya!
Daftarkan sebagai metode dalam Flight
Jika Anda menggunakan Flight PHP Framework, Anda dapat mendaftar kelas ActiveRecord sebagai layanan, tetapi sebenarnya Anda tidak perlu.
Flight::register('user', 'User', [ $pdo_connection ]);
// kemudian Anda dapat menggunakannya seperti ini di kontroler, fungsi, dll.
Flight::user()->find(1);
Metode runway
runway adalah alat CLI untuk Flight yang memiliki perintah khusus untuk pustaka ini.
# Penggunaan
php runway make:record database_table_name [class_name]
# Contoh
php runway make:record users
Ini akan membuat kelas baru di direktori app/records/
sebagai UserRecord.php
dengan konten berikut:
<?php
declare(strict_types=1);
namespace app\records;
/**
* Kelas ActiveRecord untuk tabel pengguna.
* @link https://docs.flightphp.com/awesome-plugins/active-record
*
* @property int $id
* @property string $username
* @property string $email
* @property string $password_hash
* @property string $created_dt
*/
class UserRecord extends \flight\ActiveRecord
{
/**
* @var array $relations Tetapkan hubungan untuk model
* https://docs.flightphp.com/awesome-plugins/active-record#relationships
*/
protected array $relations = [
// 'relation_name' => [ self::HAS_MANY, 'RelatedClass', 'foreign_key' ],
];
/**
* Konstruktor
* @param mixed $databaseConnection Koneksi ke basis data
*/
public function __construct($databaseConnection)
{
parent::__construct($databaseConnection, 'users');
}
}
Fungsi CRUD
find($id = null) : boolean|ActiveRecord
Temukan satu rekaman dan tetapkan ke objek saat ini. Jika Anda melewatkan $id
dari jenis tertentu, itu akan melakukan lookup pada kunci utama dengan nilai tersebut. Jika tidak ada yang dilewatkan, itu hanya akan menemukan rekaman pertama di tabel.
Selain itu, Anda dapat melewatkan metode bantu lainnya untuk kueri tabel Anda.
// temukan rekaman dengan beberapa kondisi sebelumnya
$user->notNull('password')->orderBy('id DESC')->find();
// temukan rekaman berdasarkan id tertentu
$id = 123;
$user->find($id);
findAll(): array<int,ActiveRecord>
Menemukan semua rekaman dalam tabel yang Anda tentukan.
$user->findAll();
isHydrated(): boolean
(v0.4.0)
Mengembalikan true
jika rekaman saat ini telah dihidrasi (diambil dari basis data).
$user->find(1);
// jika rekaman ditemukan dengan data...
$user->isHydrated(); // true
insert(): boolean|ActiveRecord
Menyisipkan rekaman saat ini ke dalam basis data.
$user = new User($pdo_connection);
$user->name = 'demo';
$user->password = md5('demo');
$user->insert();
Kunci Utama Berbasis Teks
Jika Anda memiliki kunci utama berbasis teks (seperti UUID), Anda dapat menetapkan nilai kunci utama sebelum menyisipkan dengan salah satu dari dua cara.
$user = new User($pdo_connection, [ 'primaryKey' => 'uuid' ]);
$user->uuid = 'some-uuid';
$user->name = 'demo';
$user->password = md5('demo');
$user->insert(); // atau $user->save();
atau Anda dapat membuat kunci utama secara otomatis untuk Anda melalui peristiwa.
class User extends flight\ActiveRecord {
public function __construct($database_connection)
{
parent::__construct($database_connection, 'users', [ 'primaryKey' => 'uuid' ]);
// Anda juga dapat menetapkan primaryKey ini dengan cara ini sebagai pengganti array di atas.
$this->primaryKey = 'uuid';
}
protected function beforeInsert(self $self) {
$self->uuid = uniqid(); // atau bagaimana pun Anda perlu membuat id unik Anda
}
}
Jika Anda tidak menetapkan kunci utama sebelum menyisipkan, itu akan disetel ke rowid
dan basis data akan menghasilkan untuk Anda, tetapi tidak akan bertahan karena field tersebut mungkin tidak ada di tabel Anda. Inilah sebabnya mengapa disarankan untuk menggunakan peristiwa untuk menangani ini secara otomatis untuk Anda.
update(): boolean|ActiveRecord
Memperbarui rekaman saat ini ke dalam basis data.
$user->greaterThan('id', 0)->orderBy('id desc')->find();
$user->email = 'test@example.com';
$user->update();
save(): boolean|ActiveRecord
Menyisipkan atau memperbarui rekaman saat ini ke dalam basis data. Jika rekaman memiliki id, itu akan diperbarui, jika tidak akan disisipkan.
$user = new User($pdo_connection);
$user->name = 'demo';
$user->password = md5('demo');
$user->save();
Catatan: Jika Anda memiliki hubungan yang ditentukan dalam kelas, itu akan secara rekursif menyimpan hubungan tersebut juga jika telah ditentukan, diinstansiasi, dan memiliki data kotor untuk diperbarui. (v0.4.0 dan lebih tinggi)
delete(): boolean
Menghapus rekaman saat ini dari basis data.
$user->gt('id', 0)->orderBy('id desc')->find();
$user->delete();
Anda juga dapat menghapus beberapa rekaman dengan melakukan pencarian terlebih dahulu.
$user->like('name', 'Bob%')->delete();
dirty(array $dirty = []): ActiveRecord
Data kotor mengacu pada data yang telah diubah dalam suatu rekaman.
$user->greaterThan('id', 0)->orderBy('id desc')->find();
// tidak ada yang "kotor" pada saat ini.
$user->email = 'test@example.com'; // sekarang email dianggap "kotor" karena sudah diubah.
$user->update();
// sekarang tidak ada data yang kotor karena sudah diperbarui dan dipertahankan di basis data
$user->password = password_hash('newpassword'); // sekarang ini kotor
$user->dirty(); // melewatkan tidak ada yang akan membersihkan semua entri kotor.
$user->update(); // tidak ada yang akan memperbarui karena tidak ada yang tertangkap sebagai kotor.
$user->dirty([ 'name' => 'something', 'password' => password_hash('a different password') ]);
$user->update(); // baik nama dan password diperbarui.
copyFrom(array $data): ActiveRecord
(v0.4.0)
Ini adalah alias untuk metode dirty()
. Ini sedikit lebih jelas tentang apa yang Anda lakukan.
$user->copyFrom([ 'name' => 'something', 'password' => password_hash('a different password') ]);
$user->update(); // baik nama dan password diperbarui.
Awesome-plugins/latte
Latte
Latte adalah mesin templating dengan fitur lengkap yang sangat mudah digunakan dan terasa lebih dekat dengan sintaks PHP dibandingkan Twig atau Smarty. Ini juga sangat mudah untuk diperluas dan menambahkan filter serta fungsi Anda sendiri.
Instalasi
Instal dengan composer.
composer require latte/latte
Konfigurasi Dasar
Ada beberapa opsi konfigurasi dasar untuk memulai. Anda dapat membaca lebih lanjut tentang mereka di Dokumentasi Latte.
use Latte\Engine as LatteEngine;
require 'vendor/autoload.php';
$app = Flight::app();
$app->register('latte', LatteEngine::class, [], function(LatteEngine $latte) use ($app) {
// Di sinilah Latte akan menyimpan cache untuk template Anda untuk mempercepat proses
// Satu hal menarik tentang Latte adalah bahwa ia secara otomatis menyegarkan
// cache saat Anda membuat perubahan pada template Anda!
$latte->setTempDirectory(__DIR__ . '/../cache/');
// Beri tahu Latte di mana direktori root untuk tampilan Anda akan berada.
// $app->get('flight.views.path') diatur di file config.php
// Anda juga bisa melakukan sesuatu seperti `__DIR__ . '/../views/'`
$latte->setLoader(new \Latte\Loaders\FileLoader($app->get('flight.views.path')));
});
Contoh Layout Sederhana
Ini adalah contoh sederhana dari file layout. Ini adalah file yang akan digunakan untuk membungkus semua tampilan Anda yang lain.
<!-- app/views/layout.latte -->
<!doctype html>
<html lang="en">
<head>
<title>{$title ? $title . ' - '}Aplikasi Saya</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav>
<!-- elemen navigasi Anda di sini -->
</nav>
</header>
<div id="content">
<!-- Ini adalah keajaiban yang terjadi di sini -->
{block content}{/block}
</div>
<div id="footer">
© Hak Cipta
</div>
</body>
</html>
Dan sekarang kita memiliki file Anda yang akan dirender di dalam blok konten tersebut:
<!-- app/views/home.latte -->
<!-- Ini memberi tahu Latte bahwa file ini "di dalam" file layout.latte -->
{extends layout.latte}
<!-- Ini adalah konten yang akan dirender di dalam layout di dalam blok konten -->
{block content}
<h1>Halaman Utama</h1>
<p>Selamat datang di aplikasi saya!</p>
{/block}
Kemudian saat Anda pergi untuk merender ini di dalam fungsi atau kontroler Anda, Anda akan melakukan sesuatu seperti ini:
// rute sederhana
Flight::route('/', function () {
Flight::latte()->render('home.latte', [
'title' => 'Halaman Utama'
]);
});
// atau jika Anda menggunakan kontroler
Flight::route('/', [HomeController::class, 'index']);
// HomeController.php
class HomeController
{
public function index()
{
Flight::latte()->render('home.latte', [
'title' => 'Halaman Utama'
]);
}
}
Lihat Dokumentasi Latte untuk informasi lebih lanjut tentang cara menggunakan Latte untuk potensi penuh!
Awesome-plugins/awesome_plugins
Plugin yang Menakjubkan
Flight sangat dapat diperluas. Ada sejumlah plugin yang dapat digunakan untuk menambahkan fungsionalitas pada aplikasi Flight Anda. Beberapa didukung secara resmi oleh Tim Flight dan yang lainnya adalah pustaka mikro/lite untuk membantu Anda memulai.
Autentikasi/Otorisasi
Autentikasi dan Otorisasi sangat penting untuk aplikasi apa pun yang memerlukan kontrol tentang siapa yang dapat mengakses apa.
- flightphp/permissions - Pustaka Izin Flight resmi. Pustaka ini adalah cara sederhana untuk menambahkan izin tingkat pengguna dan aplikasi ke aplikasi Anda.
Penyimpanan Sementara
Penyimpanan sementara adalah cara yang bagus untuk mempercepat aplikasi Anda. Ada beberapa pustaka penyimpanan sementara yang dapat digunakan dengan Flight.
- Wruczek/PHP-File-Cache - Kelas penyimpanan sementara PHP di-file yang ringan, sederhana, dan mandiri
CLI
Aplikasi CLI adalah cara yang baik untuk berinteraksi dengan aplikasi Anda. Anda dapat menggunakannya untuk menghasilkan pengendali, menampilkan semua rute, dan lainnya.
- flightphp/runway - Runway adalah aplikasi CLI yang membantu Anda mengelola aplikasi Flight Anda.
Kue
Kue adalah cara yang bagus untuk menyimpan sedikit data di sisi klien. Mereka dapat digunakan untuk menyimpan preferensi pengguna, pengaturan aplikasi, dan lainnya.
- overclokk/cookie - PHP Cookie adalah pustaka PHP yang menyediakan cara sederhana dan efektif untuk mengelola kue.
Pen-debugan
Pen-debugan sangat penting saat Anda mengembangkan di lingkungan lokal Anda. Ada beberapa plugin yang dapat meningkatkan pengalaman pen-debugan Anda.
- tracy/tracy - Ini adalah pengendali kesalahan fitur lengkap yang dapat digunakan dengan Flight. Ini memiliki sejumlah panel yang dapat membantu Anda men-debug aplikasi Anda. Ini juga sangat mudah untuk diperluas dan menambahkan panel Anda sendiri.
- flightphp/tracy-extensions - Digunakan dengan pengendali kesalahan Tracy, plugin ini menambahkan beberapa panel ekstra untuk membantu dengan pen-debugan khusus untuk proyek Flight.
Basis Data
Basis data adalah inti dari sebagian besar aplikasi. Ini adalah bagaimana Anda menyimpan dan mengambil data. Beberapa pustaka basis data adalah pembungkus untuk menulis kueri dan beberapa adalah ORM yang sepenuhnya berfungsi.
- flightphp/core PdoWrapper - Pembungkus PDO Flight resmi yang merupakan bagian dari inti. Ini adalah pembungkus sederhana untuk membantu menyederhanakan proses menulis kueri dan mengeksekusinya. Ini bukan ORM.
- flightphp/active-record - ORM/Pemetaan ActiveRecord Flight resmi. Pustaka kecil yang hebat untuk dengan mudah mengambil dan menyimpan data di basis data Anda.
Enkripsi
Enkripsi sangat penting untuk aplikasi apa pun yang menyimpan data sensitif. Melakukan enkripsi dan dekripsi data tidak terlalu sulit, tetapi menyimpan kunci enkripsi dengan benar dapat menjadi sulit. Hal yang paling penting adalah jangan pernah menyimpan kunci enkripsi Anda di direktori publik atau mengkomitnya ke repositori kode Anda.
- defuse/php-encryption - Ini adalah pustaka yang dapat digunakan untuk mengenkripsi dan mendekripsi data. Memulai cukup sederhana untuk mulai mengenkripsi dan mendekripsi data.
Sesi
Sesi tidak begitu berguna untuk API, tetapi untuk membangun aplikasi web, sesi dapat sangat penting untuk mempertahankan status dan informasi login.
- Ghostff/Session - Pengelola Sesi PHP (non-blocking, flash, segment, enkripsi sesi). Menggunakan PHP open_ssl untuk enkripsi/dekripsi opsional data sesi.
Penataan
Penataan adalah inti dari aplikasi web mana pun dengan antarmuka pengguna. Ada sejumlah mesin penataan yang dapat digunakan dengan Flight.
- flightphp/core View - Ini adalah mesin penataan yang sangat dasar yang merupakan bagian dari inti. Tidak disarankan untuk digunakan jika Anda memiliki lebih dari beberapa halaman di proyek Anda.
- latte/latte - Latte adalah mesin penataan fitur lengkap yang sangat mudah digunakan dan terasa lebih dekat dengan sintaksis PHP daripada Twig atau Smarty. Ini juga sangat mudah untuk diperluas dan menambahkan filter dan fungsi Anda sendiri.
Berkontribusi
Apakah Anda memiliki plugin yang ingin Anda bagikan? Kirimkan permintaan tarik untuk menambahkannya ke daftar!
Media
Media
Kami telah berusaha untuk melacak apa yang kami bisa dari berbagai jenis media di internet tentang Flight. Lihat di bawah untuk berbagai sumber yang dapat Anda gunakan untuk mempelajari lebih lanjut tentang Flight.
Artikel
- Best PHP Micro Frameworks for 2024 oleh n0nag0n (2024)
- Creating a RESTful API with Flight Framework oleh n0nag0n (2024)
- Building a Simple Blog with Flight Part 2 oleh n0nag0n (2024)
- Building a Simple Blog with Flight Part 1 oleh n0nag0n (2024)
- 🚀 Build a Simple CRUD API in PHP with the Flight Framework oleh soheil-khaledabadi (2024)
- Building a PHP Web Application with the Flight Micro-framework oleh Arthur C. Codex (2023)
- Best PHP Frameworks for Web Development in 2024 oleh Ravikiran A S (2023)
- Top 12 PHP Frameworks: A Comprehensive Guide for 2023 oleh marketing kbk (2023)
- 5 PHP Frameworks You've (Probably) Never Heard of oleh n0nag0n (2022)
- 12 top PHP frameworks for web developers to consider in 2023 oleh Anna Monus (2022)
- The Best PHP Microframeworks on a Cloud Server oleh Shahzeb Ahmed (2021)
- PHP framework: Top 15 powerful ones for your web development oleh AHT Tech (2020)
- Easy PHP Routing with FlightPHP oleh Lucas Conceição (2019)
- Trying Out New PHP Framework (Flight) oleh Leon (2017)
- Setting up FlightPHP to work with Backbonejs oleh Timothy Tocci (2015)
Video
- PHP Flight Framework Simple Introductory Video oleh n0nag0n (2024)
- Set header HTTP code in Flightphp (3 Solutions!!) oleh Roel Van de Paar (2024)
- PHP Flight Framework Tutorial. Super easy API Project! oleh n0nag0n (2022)
- Aplicación web CRUD con php y mysql y bootstrap usando flight oleh Devlopteca - Oscar Uh (2021)
- DevOps & SysAdmins: Lighttpd rewrite rule for Flight PHP microframework oleh Roel Van de Paar (2021)
- Tutorial REST API Flight PHP #PART2 INSERT TABLE Info #Code (Tagalog) oleh Info Singkat Official (2020)
- Tutorial REST API Flight PHP #PART1 Info #Code (Tagalog) oleh Info Singkat Official (2020)
- How To Create JSON REST API IN PHP - Part 2 oleh Codewife (2018)
- How To Create JSON REST API IN PHP - Part 1 oleh Codewife (2018)
- Teste Micro Frameworks PHP - Flight PHP, Lumen, Slim 3 e Laravel oleh Codemarket (2016)
- Tutorial 1 Flight PHP - Instalación oleh absagg (2014)
- Tutorial 2 Flight PHP - Route parte 1 oleh absagg (2014)
Examples
Butuh memulai dengan cepat?
Anda memiliki dua opsi untuk memulai dengan Flight:
- Single File Skeleton Boilerplate: Sebuah file tunggal yang mencakup semua yang Anda butuhkan untuk menjalankan aplikasi Anda dalam satu file sederhana.
- Full Skeleton Boilerplate: Contoh yang lebih lengkap dengan pengendali dan tampilan.
Butuh Inspirasi?
Meskipun ini tidak secara resmi disponsori oleh Tim Flight, ini dapat memberikan Anda ide tentang bagaimana menyusun proyek Anda sendiri yang dibangun dengan Flight!
- Flight Example Blog - Flight v3 dengan Middleware, Pengendali, Active Record, dan Latte.
- Flight CRUD RESTful API - Proyek API CRUD sederhana menggunakan framework Flight, yang menyediakan struktur dasar bagi pengguna baru untuk dengan cepat menyiapkan aplikasi PHP dengan operasi CRUD dan konektivitas basis data. Proyek ini menunjukkan bagaimana menggunakan Flight untuk pengembangan API RESTful, menjadikannya alat belajar yang ideal bagi pemula dan kit awal yang berguna bagi pengembang yang lebih berpengalaman.
- Flight School Management System - Flight v3
- Paste Bin with Comments - Flight v3
- Basic Skeleton App
- Example Wiki
- The IT-Innovator PHP Framework Application
- LittleEducationalCMS (Spanish)
- Italian Yellow Pages API
- Generic Content Management System (with....very little documentation)
- A tiny php framework based on Flight and medoo.
- Example MVC Application
Ingin Membagikan Contoh Anda Sendiri?
Jika Anda memiliki proyek yang ingin Anda bagikan, silakan kirim permintaan tarik untuk menambahkannya ke daftar ini!
Install/install
Instalasi
Unduh berkas
Pastikan Anda memiliki PHP terinstal di sistem Anda. Jika tidak, klik di sini untuk petunjuk tentang cara menginstalnya di sistem Anda.
Jika Anda menggunakan Composer, Anda dapat menjalankan perintah berikut:
composer require flightphp/core
ATAU Anda dapat mengunduh berkas langsung dan mengekstraknya ke direktori web Anda.
Konfigurasikan Server Web Anda
Server Pengembangan PHP Bawaan
Ini adalah cara termudah untuk memulai dan menjalankan aplikasi. Anda dapat menggunakan server bawaan untuk menjalankan aplikasi Anda dan bahkan menggunakan SQLite untuk basis data (selama sqlite3 terinstal di sistem Anda) dan tidak memerlukan banyak hal! Jalankan perintah berikut setelah PHP terinstal:
php -S localhost:8000
Kemudian buka browser Anda dan pergi ke http://localhost:8000
.
Jika Anda ingin membuat akar dokumen proyek Anda ke direktori yang berbeda (Mis: proyek Anda adalah ~/myproject
, tetapi akar dokumen Anda adalah ~/myproject/public/
), Anda dapat menjalankan perintah berikut setelah Anda berada di direktori ~/myproject
:
php -S localhost:8000 -t public/
Kemudian buka browser Anda dan pergi ke http://localhost:8000
.
Apache
Pastikan Apache sudah terinstal di sistem Anda. Jika tidak, cari tahu cara menginstal Apache di sistem Anda.
Untuk Apache, edit file .htaccess
Anda dengan yang berikut:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Catatan: Jika Anda perlu menggunakan flight di subdirektori, tambahkan baris
RewriteBase /subdir/
tepat setelahRewriteEngine On
.Catatan: Jika Anda ingin melindungi semua berkas server, seperti berkas db atau env. Tempatkan ini di file
.htaccess
Anda:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Nginx
Pastikan Nginx sudah terinstal di sistem Anda. Jika tidak, cari tahu cara menginstal Nginx di sistem Anda.
Untuk Nginx, tambahkan yang berikut ke deklarasi server Anda:
server {
location / {
try_files $uri $uri/ /index.php;
}
}
Buat file index.php
Anda
<?php
// Jika Anda menggunakan Composer, persyaratan autoloader.
require 'vendor/autoload.php';
// jika Anda tidak menggunakan Composer, muat kerangka kerja secara langsung
// require 'flight/Flight.php';
// Kemudian tetapkan rute dan tetapkan fungsi untuk menangani permintaan.
Flight::route('/', function () {
echo 'hello world!';
});
// Akhirnya, mulai kerangka kerja.
Flight::start();
Instalasi PHP
Jika Anda sudah memiliki php
terinstal di sistem Anda, silakan lewati petunjuk ini dan lanjut ke bagian unduh
macOS
Menginstal PHP menggunakan Homebrew
-
Instal Homebrew (jika belum terinstal):
- Buka Terminal dan jalankan:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- Buka Terminal dan jalankan:
-
Instal PHP:
- Instal versi terbaru:
brew install php
- Untuk menginstal versi tertentu, misalnya, PHP 8.1:
brew tap shivammathur/php brew install shivammathur/php/php@8.1
- Instal versi terbaru:
-
Beralih antara versi PHP:
- Lepaskan versi saat ini dan tautkan versi yang diinginkan:
brew unlink php brew link --overwrite --force php@8.1
- Verifikasi versi yang diinstal:
php -v
- Lepaskan versi saat ini dan tautkan versi yang diinginkan:
Windows 10/11
Menginstal PHP secara manual
-
Unduh PHP:
- Kunjungi PHP untuk Windows dan unduh versi terbaru atau versi tertentu (misalnya, 7.4, 8.0) sebagai berkas zip yang tidak aman untuk thread.
-
Ekstrak PHP:
- Ekstrak berkas zip yang diunduh ke
C:\php
.
- Ekstrak berkas zip yang diunduh ke
-
Tambahkan PHP ke PATH sistem:
- Masuk ke Properti Sistem > Variabel Lingkungan.
- Di bawah variabel sistem, cari Path dan klik Edit.
- Tambahkan jalur
C:\php
(atau di mana pun Anda mengekstrak PHP). - Klik OK untuk menutup semua jendela.
-
Konfigurasi PHP:
- Salin
php.ini-development
kephp.ini
. - Edit
php.ini
untuk mengonfigurasi PHP sesuai kebutuhan (misalnya, mengaturextension_dir
, mengaktifkan ekstensi).
- Salin
-
Verifikasi instalasi PHP:
- Buka Command Prompt dan jalankan:
php -v
- Buka Command Prompt dan jalankan:
Menginstal Beberapa Versi PHP
-
Ulangi langkah di atas untuk setiap versi, menempatkan masing-masing di direktori terpisah (misalnya,
C:\php7
,C:\php8
). -
Beralih antara versi dengan menyesuaikan variabel PATH sistem untuk menunjuk ke direktori versi yang diinginkan.
Ubuntu (20.04, 22.04, dll.)
Menginstal PHP menggunakan apt
-
Perbarui daftar paket:
- Buka Terminal dan jalankan:
sudo apt update
- Buka Terminal dan jalankan:
-
Instal PHP:
- Instal versi PHP terbaru:
sudo apt install php
- Untuk menginstal versi tertentu, misalnya, PHP 8.1:
sudo apt install php8.1
- Instal versi PHP terbaru:
-
Instal modul tambahan (opsional):
- Misalnya, untuk menginstal dukungan MySQL:
sudo apt install php8.1-mysql
- Misalnya, untuk menginstal dukungan MySQL:
-
Beralih antara versi PHP:
- Gunakan
update-alternatives
:sudo update-alternatives --set php /usr/bin/php8.1
- Gunakan
-
Verifikasi versi yang diinstal:
- Jalankan:
php -v
- Jalankan:
Rocky Linux
Menginstal PHP menggunakan yum/dnf
-
Aktifkan repositori EPEL:
- Buka Terminal dan jalankan:
sudo dnf install epel-release
- Buka Terminal dan jalankan:
-
Instal repositori Remi:
- Jalankan:
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm sudo dnf module reset php
- Jalankan:
-
Instal PHP:
- Untuk menginstal versi default:
sudo dnf install php
- Untuk menginstal versi tertentu, misalnya, PHP 7.4:
sudo dnf module install php:remi-7.4
- Untuk menginstal versi default:
-
Beralih antara versi PHP:
- Gunakan perintah modul
dnf
:sudo dnf module reset php sudo dnf module enable php:remi-8.0 sudo dnf install php
- Gunakan perintah modul
-
Verifikasi versi yang diinstal:
- Jalankan:
php -v
- Jalankan:
Catatan Umum
- Untuk lingkungan pengembangan, penting untuk mengonfigurasi pengaturan PHP sesuai dengan kebutuhan proyek Anda.
- Saat beralih antara versi PHP, pastikan semua ekstensi PHP yang relevan terinstal untuk versi tertentu yang ingin Anda gunakan.
- Restart server web Anda (Apache, Nginx, dll.) setelah beralih versi PHP atau memperbarui konfigurasi untuk menerapkan perubahan.