เฟรมเวิร์ก PHP ขนาดเล็กที่ปรับได้ซึ่งพยายามหลีกเลี่ยงทางของคุณ
งานอยู่ระหว่างดำเนินการเป็นอย่างมากใช้ความเสี่ยงของคุณเอง ...
ความแน่นอนของความตาย โอกาสเล็ก ๆ น้อย ๆ ที่ประสบความสำเร็จ เราจะรออะไรอยู่?
composer require danc0/gimliduck-php
สร้างโครงการโครงกระดูกด้วย: composer create-project danc0/gimli-skeleton
เพิ่ม devtools ด้วย composer require --dev danc0/gimliduck-devtools
สร้างไฟล์ .htaccess ที่มีลักษณะเช่นนี้เพื่อขอจุดขอไปยังไฟล์ index.php ของคุณ
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
การสร้างแอปพลิเคชัน Gimliduck นั้นง่าย:
declare (strict_types= 1 );
require_once __DIR__ . ' /vendor/autoload.php ' ;
use Gimli Application ;
use Gimli Router Route ;
Application:: create ( __DIR__ , $ _SERVER );
Route:: get ( ' / ' , function (){
echo " Hello World " ;
});
Application:: start ();นั่นคือทั้งหมดที่คุณต้องเริ่มต้น คุณสามารถเพิ่มเช่นเอ็นจิ้นเทมเพลตไฟล์กำหนดค่า ฯลฯ แต่คุณไม่ จำเป็น ต้องทำ
<?php
declare (strict_types= 1 );
require_once __DIR__ . ' /vendor/autoload.php ' ;
use Gimli Application ;
use App Core Config ;
use App Core Cache ;
define ( ' APP_ROOT ' , __DIR__ );
$ App = Application:: create ( APP_ROOT , $ _SERVER );
// set up your config and add it to the Application
$ config_file = parse_ini_file ( APP_ROOT . ' /App/Core/config.ini ' , true );
$ App -> Config = $ App -> Injector -> resolveFresh (Config::class, [ ' config ' => $ config_file ]);
// Register a cache class with the Injector
$ App -> Injector -> register (Cache::class, Cache:: getCache ( $ App -> Config -> admin_cache ));
// Run Application
$ App -> run (); คลาส Application ยังลงทะเบียนตัวจัดการเหตุการณ์พื้นฐานและคลาสเซสชันเมื่อสร้างขึ้น นอกจากนี้หากการกำหนดค่าของคุณรวมถึง enable_latte เอ็นจิ้นเทมเพลต Latte จะถูกเพิ่มลงในอินสแตนซ์แอปพลิเคชันโดยใช้ค่า config สำหรับ template_base_dir เป็นไดเรกทอรีเทมเพลต
โดยค่าเริ่มต้น GIMLI จะต้องใช้ไฟล์ใด ๆ ในไดเรกทอรี App/Routes คุณสามารถปิดการใช้งานสิ่งนี้ได้โดยการตั้งค่า autoload_routes เป็น false ในไฟล์กำหนดค่าของคุณ คุณสามารถเปลี่ยนไดเรกทอรีได้โดยการตั้งค่า route_directory ในไฟล์กำหนดค่าของคุณ นอกจากนี้คุณยังสามารถโหลดไฟล์เส้นทางเพิ่มเติมด้วยวิธีการต่อไปนี้:
// Load routes from a file(s)
$ App -> loadRouteFiles ([
' App/routes/web.php ' ,
]);มีบางสิ่งที่คุณสามารถทำได้กับการโทรกลับเส้นทางของคุณ ... ผ่านสตริงสายเรียกเข้าหรืออาร์เรย์
Route::get( ' / ' , function (){
echo " Hello World "
});
// Single action controller, must use __invoke method
Route:: get ( ' / ' , Home_Controller::class);
// cli routes are single action Job classes
Route:: cli ( ' build-cache ' , Cache_Job::class);
Route:: get ( ' / ' , Home_Controller::class . ' @homePage ' );
Route:: get ( ' / ' , [Home_Controller::class, ' homePage ' ]);งานเหล่านั้นขึ้นอยู่กับคุณว่าคุณทำอย่างไร
คุณสามารถเพิ่มมิดเดิลแวร์หากคุณต้องการการป้องกันพิเศษ
Route:: get ( ' / ' , [Home_Controller::class, ' homePage ' ])-> addMiddleware (Logged_In_Middleware::class); นั่นควรเป็นคลาสที่ใช้ GimliMiddlewareMiddleware_Interface ซึ่งต้องใช้วิธี process ที่ส่งคืน GimliMiddlewareMiddleware_Response มิดเดิลแวร์สามารถเข้าถึงอินสแตนซ์ของแอปพลิเคชันรวมถึงหัวฉีดและสิ่งอื่นใดที่คุณตัดสินใจตั้งค่า
นอกจากนี้คุณยังสามารถเพิ่มกลุ่มกำหนดไฟล์เส้นทางเริ่มต้นที่ควรโหลดและโหลดไฟล์เส้นทางเพิ่มเติมเพื่อช่วยจัดระเบียบเส้นทางของคุณ
เส้นทางของคุณยังสามารถมีอาร์กิวเมนต์ตัวแปรที่ตรงกับรูปแบบต่อไปนี้:
protected array $ patterns = [
' :all ' => " ([^/]+) " ,
' :alpha ' => " ([A-Za-z_-]+) " ,
' :alphanumeric ' => " ([w-]+) " ,
' :integer ' => " ([0-9_-]+) " ,
' :numeric ' => " ([0-9_-.]+) " ,
' :id ' => " ([0-9_-]+) " ,
' :slug ' => " ([A-Za-z0-9_-]+) " ,
]; คุณจะต้องเพิ่มชื่อตัวแปรโดยใช้สัญลักษณ์ # ในนิยามเส้นทาง
Route:: get ( ' /user/:integer#id ' , [User_Controller::class, ' getUser ' ]); ชื่อตัวแปรนี้จะถูกส่งผ่านไปยังเราเตอร์และตั้งค่าเป็นการพึ่งพาวิธีคอนโทรลเลอร์ของคุณ คุณควรใช้ชื่อตัวแปรที่กำหนดเป็นอาร์กิวเมนต์ในวิธีคอนโทรลเลอร์ของคุณ ค่าจะเป็น typecast ตามประเภทที่มีอยู่สำหรับ settype , ประเภทที่เป็นไปได้:
integer or int
float or double
string
array
object
boolean or bool
ตัวอย่างวิธีการควบคุม:
public function getUser ( Response $ Response , int $ id ): Response {
// do something with $id
} คอนโทรลเลอร์ควรส่งคืนวัตถุ GimliHttpResponse มีวิธีการของผู้ช่วยที่ส่งคืนวัตถุ Response ที่จัดรูปแบบเพื่อช่วย จำกัด ตรรกะเงื่อนไขบางประการ:
response การตอบสนองพื้นฐานredirect การตอบสนองการเปลี่ยนเส้นทางredirect_on_success เปลี่ยนเส้นทางหากการตอบกลับสำเร็จredirect_on_failure เปลี่ยนเส้นทางหากการตอบกลับไม่สำเร็จjson_response JSON ไฟล์งานจะได้ subcommand อาร์กิวเมนต์ options และ flags ต่อไปนี้ อาร์กิวเมนต์ options คืออาร์เรย์ของอาร์เรย์ที่มีชื่อและค่า อาร์กิวเมนต์ flags เป็นอาร์เรย์ที่มีธงที่กำหนด อาร์กิวเมนต์ subcommand เป็นเพียงสตริงหากได้รับคำสั่งย่อย
คุณสามารถใช้หัวฉีดในตัวเพื่อผูกหรือลงทะเบียนการพึ่งพา คุณยังสามารถแก้ไขการพึ่งพาจากหัวฉีด คุณสามารถเพิ่มสิ่งที่คุณต้องการในหัวฉีดและเข้าถึงได้ตลอดแอปพลิเคชันของคุณผ่านอินสแตนซ์ Application เคชัน
หัวฉีดในตัวจะคลาส AutoWire และแก้ไขการพึ่งพาตามความจำเป็น นอกจากนี้คุณยังสามารถผูกคลาสกับการปิดได้หากคุณต้องการตั้งค่าบางอย่างก่อนที่จะกลับคลาสหรือลงทะเบียนวัตถุที่สร้างขึ้นแล้ว ตัวอย่างด้านล่างแสดงคอนโทรลเลอร์แอ็คชั่นเดียวที่จะได้รับการแก้ไขจากคลาสเราเตอร์ พารามิเตอร์ __construct Method ได้รับการแก้ไขจากหัวฉีด
<?php
declare (strict_types= 1 );
namespace App Controllers ;
use App Logic Dashboard_Logic ;
use Gimli Http Response ;
use Gimli Application ;
use Gimli View Latte_Engine ;
class Dashboard_Landing_Controller {
/**
* Constructor
*
* @param Application $Application
*/
public function __construct (
public Application $ Application ,
protected Dashboard_Logic $ Dashboard_Logic ,
protected Latte_Engine $ View
){
//
}
/**
* Single action controller call
*
* @return Response
*/
public function __invoke ( Response $ Response ): Response {
$ template_data = $ this -> Dashboard_Logic -> getTemplateData ();
return $ Response -> setResponse ( $ this -> View -> render ( ' dashboard/dashboard.latte ' , $ template_data ));
}
}พารามิเตอร์วิธีการได้รับการแก้ไขโดยหัวฉีดเมื่อเส้นทางส่งวิธีการ
นอกจากนี้ยังมีวิธีผู้ช่วยหัวฉีดที่ลดรหัสอินไลน์บางอย่าง โดยทั่วไปหากคุณต้องการฉีดคลาสอินไลน์คุณสามารถทำได้ด้วย $this->Application->Injector->resolve(Some_Class::class) หรือ Application::get()->Injector->resolve(Some_Class::class) วิธี resolve และ resolve_fresh พร้อมใช้งานเพื่อตัดรหัสอินไลน์นั้น
มี Database Wrapper PDO พื้นฐานรวมถึงคลาส Pdo_Manager ที่คุณสามารถใช้เพื่อจัดการการสืบค้นฐานข้อมูล คลาส Pdo_Manager ส่งคืนและอินสแตนซ์ของ PDO และสามารถใช้ในการเรียกใช้การสืบค้นโดยตรง คลาส Database เป็น wrapper รอบคลาส Pdo_Manager และให้วิธีการสืบค้นพื้นฐานบางอย่าง นอกจากนี้ยังมีคลาสฐาน Model พื้นฐานมากและวิธีการช่วยเพิ่มเติมสำหรับ Database เช่นที่อื่น ๆ วิธีการเหล่านี้จัดการการฉีดพึ่งพาและเรียกใช้วิธีการในคลาส Database ที่ฉีด ผู้ช่วยคือ:
fetch_columnfetch_rowfetch_allrow_exists มีคลาส seeder พื้นฐานที่สามารถใช้ในการเพาะเมล็ดฐานข้อมูลของคุณ สิ่งนี้ขึ้นอยู่กับคุณลักษณะที่วางไว้ในคลาสโมเดลเพื่อ Seeder วิธีสร้างข้อมูล
<?php
declare (strict_types= 1 );
namespace Gimli Database ;
use Gimli Database Model ;
use Gimli Database Seed ;
class User_Model extends Model {
/**
* @var string $table_name
*/
protected string $ table_name = ' users ' ;
/**
* ID
*
* @var int $id
*/
public $ id ;
/**
* Unique_Id
*
* @var string $unique_id
*/
#[Seed(type: ' unique_id ' , args: [ ' length ' => 12 ])]
public $ unique_id ;
/**
* Username
*
* @var string $username
*/
#[Seed(type: ' username ' )]
public $ username ;
/**
* Email
*
* @var string $email
*/
#[Seed(type: ' email ' )]
public $ email ;
/**
* Password
*
* @var string $password
*/
#[Seed(type: ' password ' )]
public $ password ;
/**
* Is_Active
*
* @var int $is_active
*/
#[Seed(type: ' tiny_int ' )]
public $ is_active ;
/**
* First Name
*
* @var string $first_name
*/
#[Seed(type: ' first_name ' )]
public $ first_name ;
/**
* Last Name
*
* @var string $last_name
*/
#[Seed(type: ' last_name ' )]
public $ last_name ;
/**
* Status
*
* @var int $status
*/
#[Seed(type: ' one_of ' , args: [ 0 , 1 ])]
public $ status ;
/**
* Created_At
*
* @var string $created_at
*/
#[Seed(type: ' date ' , args: [ ' format ' => ' Y-m-d H:i:s ' , ' min ' => ' 2021-01-01 ' , ' max ' => ' 2021-04-01 00:00:00 ' ])]
public $ created_at ;
/**
* Updated_At
*
* @var string $updated_at
*/
#[Seed(type: ' date ' , args: [ ' format ' => ' Y-m-d H:i:s ' , ' min ' => ' 2021-04-01 00:02:00 ' ])]
public $ updated_at ;
/**
* bio
*
* @var string $about
*/
#[Seed(type: ' paragraph ' , args: [ ' count ' => 1 ])]
public $ about ;
}จากนั้นคุณสามารถเพาะเมล็ดฐานข้อมูลด้วยรหัสต่อไปนี้:
Seeder:: make (User_Model::class)
-> seed ( 123 )
-> count ( 1 )
-> create (); แทนที่จะสร้างคุณสามารถโทรหา getSeededData เพื่อรับข้อมูลที่จะแทรกลงในฐานข้อมูล สิ่งนี้มีประโยชน์สำหรับการทดสอบหรือโหลดโมเดลด้วยตนเองโดยไม่ต้องบันทึก นอกจากนี้คุณยังสามารถผ่านวิธีการโทรกลับที่จะได้รับข้อมูลของโมเดลเริ่มต้น สิ่งนี้ช่วยในการเพาะเมล็ดข้อมูลที่เกี่ยวข้อง การโทรกลับควรส่งคืนอินสแตนซ์ของ Seeder
Seeder:: make (User_Model::class)
-> seed ( 123 )
-> count ( 1 )
-> callback ( function ( $ data ) {
return [
Seeder:: make (User_Hobby_Model::class)-> with ([ ' user_id ' => $ data [ ' id ' ]]),
Seeder:: make (User_Group_Model::class)-> with ([ ' user_id ' => $ data [ ' id ' ]]),
]
})
-> create (); เมล็ดที่ผ่านการรับรองจะช่วยให้มั่นใจได้ว่าข้อมูลจะยังคงเหมือนเดิมทุกครั้งที่มีการเรียกใช้ seeder ส่งผลให้ชุดข้อมูลที่ทำซ้ำได้ คลาส Seeder มีวิธี getRandomSeed ที่จะส่งคืนค่าเมล็ดสุ่ม สิ่งนี้มีประโยชน์สำหรับการสร้างข้อมูลแบบสุ่มที่คุณไม่จำเป็นต้องทำซ้ำหรือสร้างเมล็ดสุ่มที่คุณสามารถคัดลอกและใช้งานได้
นอกจากนี้ยังมีผู้ช่วย config บางส่วน:
get_config เพื่อรับอาร์เรย์การกำหนดค่าทั้งหมดget_config_value เพื่อรับค่าเฉพาะจากอาร์เรย์ configconfig_has เพื่อตรวจสอบว่ามีคีย์อยู่ในอาร์เรย์ config หรือไม่