당신의 길을 벗어나려고하는 적응 가능한 마이크로 PHP 프레임 워크.
진행중인 작업은 자신의 위험에 사용합니다 ...
죽음의 확실성. 성공의 작은 기회. 우리는 무엇을 기다리고 있습니까?
composer require danc0/gimliduck-php
composer create-project danc0/gimli-skeleton 사용하여 골격 프로젝트를 만듭니다
composer require --dev danc0/gimliduck-devtools 와 함께 DevTools를 추가하십시오
index.php 파일에 요청을 가리키기 위해 이와 같은 모습을 보이는 .htaccess 파일을 만듭니다.
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 포함 된 경우 template_base_dir 의 구성 값을 템플릿 디렉토리로 사용하여 Latte 템플릿 엔진이 응용 프로그램 인스턴스에 추가됩니다.
기본적으로 Gimli는 App/Routes 디렉토리의 파일이 필요합니다. 구성 파일에서 autoload_routes false 로 설정하여이를 비활성화 할 수 있습니다. 구성 파일에서 route_directory 값을 설정하여 디렉토리를 변경할 수 있습니다. 다음 방법으로 추가 경로 파일을로드 할 수도 있습니다.
// Load routes from a file(s)
$ App -> loadRouteFiles ([
' App/routes/web.php ' ,
]);Route Callbacks로 할 수있는 몇 가지가 있습니다 ... 문자열, 호출 가능 또는 배열을 통과하십시오.
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 구현하는 클래스이어야합니다. 이는 GimliMiddlewareMiddleware_Response 반환하는 process 방법이 필요합니다. 미들웨어는 인젝터와 설정하기로 결정한 모든 것을 포함하여 응용 프로그램 인스턴스에 액세스 할 수 있습니다.
또한 그룹을 추가하고로드 해야하는 기본 경로 파일을 정의하고 추가 경로 파일을로드하여 경로를 정리할 수 있습니다.
경로에는 다음 패턴을 충족하는 가변 인수도 포함 할 수도 있습니다.
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 ' ]); 이 변수 이름은 라우터로 전달되어 컨트롤러 메소드의 종속성으로 설정됩니다. 정의 된 변수 이름을 컨트롤러 메소드의 인수로 사용해야합니다. 값은 가능한 유형의 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 인스턴스를 통해 액세스 할 수 있습니다.
내장 인젝터는 클래스를 자동화하고 필요에 따라 종속성을 해결합니다. 클래스를 반환하기 전에 설정을 수행하거나 이미 생성 된 개체를 등록하기 전에 일부 설정을 수행 해야하는 경우 클래스를 클래스에 바인딩 할 수도 있습니다. 아래의 예는 라우터 클래스에서 해결 될 단일 액션 컨트롤러를 보여줍니다. __construct 메소드 매개 변수는 인젝터에서 분해됩니다.
<?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 사용할 수 있습니다.
기본 PDO 래퍼 Database 와 데이터베이스 쿼리를 관리하는 데 사용할 수있는 Pdo_Manager 클래스가 있습니다. Pdo_Manager 클래스는 PDO 의 반환 및 인스턴스이며 쿼리를 직접 실행하는 데 사용할 수 있습니다. Database 클래스는 Pdo_Manager 클래스 주변의 래퍼이며 몇 가지 기본 쿼리 방법을 제공합니다. 다른 방법과 마찬가지로 Database 대한 매우 기본적인 Model 기본 클래스 및 추가 도우미 방법도 있습니다. 이러한 방법은 종속성 주입을 처리하고 주입 된 Database 클래스에서 메소드를 호출합니다. 도우미는 다음과 같습니다.
fetch_columnfetch_rowfetch_allrow_exists 데이터베이스를 시드하는 데 사용할 수있는 기본 파종자 클래스가 있습니다. 이는 모델 클래스에 배치 된 속성에 의존하여 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 클래스에는 랜덤 시드 값을 반환하는 getRandomSeed 방법이 있습니다. 이것은 재현 할 필요가없는 임의의 데이터를 만들거나 복사 및 사용할 수있는 임의의 시드를 생성하는 데 유용합니다.
몇 가지 구성 도우미도 있습니다.
get_config 전체 구성 배열을 얻습니다get_config_valueconfig_has config 배열에 키가 존재하는지 확인합니다.