一个适应性的微型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则使用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的类,该 Middleware_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如果响应成功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类的包装器,并提供了一些基本的查询方法。还有一个非常基本的Model基类和Database的其他帮助方法,就像其他地方一样,这些方法处理依赖项注入并调用注入的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_value从配置数组中获取特定值config_has检查config Array中是否存在密钥