liftkit / liftkit
LiftKit 项目基础
Requires
- liftkit/core: ~0.5
- liftkit/database: ^2.8
- liftkit/dependency-injection: ^1.1
- liftkit/document: ^1.1
- liftkit/example-module: ~0.2
- liftkit/form: ^3.0
- liftkit/input: ^1.1
- liftkit/output: ^1.1
- liftkit/session: ^1.0
- martinlindhe/http_response_code_compat: ^1.0
Requires (Dev)
- phpunit/phpunit: ^4.5
README
安装方法
安装 composer 依赖项
composer install
在以下文件中更新数据库凭证
config/database/connection/*
控制器
控制器基础
控制器是确定要执行的操作的对象。控制器必须扩展 LiftKit\Controller\Controller
。控制器的公共方法是可能被路由到的方法。所有控制器动作都必须返回一个 LiftKit\Response\Response
实例,无论是视图(LiftKit\Response\View
的实例)、JSON 响应(LiftKit\Response\Json
的实例)还是您的自定义类型。
默认控制器
此软件包附带了一些控制器作为起点。它们位于 src/Controller
。
Controller.php
作为您所有控制器的基础类。在此处放置常用功能和加载常用库。
此文件还定义了一个 display()
方法,用于将 html 页面显示在屏幕上。您应该在此处加载常用视图(例如,页眉和页脚)。
Index.php
此控制器是您静态公开页面的主要控制器。默认情况下,它定义了显示 Iris 欢迎页和错误页的方法。
Content.php
此控制器是您应放置用户管理的页面内容的控制器。这些页面将是可内联编辑的。提供了一个基本的 interior()
方法,用于标准内容页面,没有其他动态内容或部分视图。
路由
默认情况下,路由配置存储在 config/routes/default.php
。稍后我们将讨论自定义路由配置文件。
路由器(作为 $router
可用的 LiftKit\Router\Http
的实例)提供了许多方便的方法来定义路由。
控制器路由
控制器路由“附加”一个控制器到特定的 URI。有两种定义它们的方法。
registerControllerFactory()
此方法接受一个 URI 和一个工厂函数作为参数,该工厂函数生成控制器。与 registerController()
相比,此方法更受欢迎,因为它会延迟加载类,这可以防止许多问题。
use App\Controller\SomeController;
$router->registerControllerFactory(
'/base-uri/',
function () use ($container) {
return new SomeController($container);
}
);
registerController()
此方法接受一个 URI 和控制器作为参数。此方法不建议使用。
use App\Controller\SomeController;
$router->registerController(
'/base-uri/',
new SomeController($container)
);
请求映射
上述两种方法都将控制器附加到 URI /base-uri/
。以下是对请求及其动作的映射。
注意:普通控制器路由不考虑请求方法。可以是 GET、POST、DELETE 等。
GET /base-uri
=>SomeController::index()
POST /base-uri/test
=>SomeController::test()
DELETE /base-uri/with-arg/123
=>SomeController::withArg('123')
GET /base-uri/with-two-args/123/456
=>SomeController::withTwoArgs('123', '456')
REST 控制器路由
REST 控制器路由与控制器路由类似,但控制器必须实现 \LiftKit\Controller\RestInterface
。
registerRestControllerFactory()
此方法与 registerControllerFactory()
类似,但它的工厂函数必须生成 \LiftKit\Controller\RestInterface
的实例。
use App\Controller\SomeRestController;
$router->registerRestControllerFactory(
'/base-uri/',
function () use ($container) {
return new SomeRestController($container);
}
);
registerController()
此方法与 registerController()
类似,但它必须提供 \LiftKit\Controller\RestInterface
的实例。
use App\Controller\SomeRestController;
$router->registerController(
'/base-uri/',
new SomeRestController($container)
);
请求映射
上述两种方法都将控制器附加到 URI /base-uri/
。以下是对请求及其动作的映射。在 \LiftKit\Controller\RestInterface
中定义的方法取决于使用的特定 HTTP 方法。
GET /base-uri/
=>SomeRestController::index()
POST /base-uri/
=>SomeRestController::insert()
GET /base-uri/1
=>SomeRestController::get(1)
POST /base-uri/1
=>SomeRestController::update(1)
DELETE /base-uri/1
=>SomeRestController::delete(1)
将添加到控制器中的任何其他方法都将路由到,无论HTTP方法。
GET /base-uri/test-action
=>SomeRestController::testAction()
POST /base-uri/another-action
=>SomeRestController::anotherAction()
模式路由
模式基础
模式路由将URI模式匹配到操作。模式路由可以使用命名的占位符作为参数。第一个参数是要匹配的URI模式,第二个参数是在模式匹配时执行的一个回调函数。第三个参数是模式应该应用的HTTP方法的可选参数。
与控制器操作类似,模式路由的回调函数必须返回一个LiftKit\Response\Response
实例。
$router->registerPattern(
'/products',
function ()
{
// DO SOMETHING
},
'GET'
);
带占位符的模式
模式还可以接受命名的占位符。命名的占位符前面有一个:
,必须在setPlaceholder()
的链式调用中定义。setPlaceholder()
接受两个参数,第一个是占位符的标识符(不含:
),第二个是匹配正确字符序列的正则表达式类。有几个内置的模式,例如LiftKit\Router\Route\Http\Pattern\Pattern::DIGITS
、LiftKit\Router\Route\Http\Pattern\Pattern::SLUG
和LiftKit\Router\Route\Http\Pattern\Pattern::ALPHA_NUM
。
use LiftKit\Router\Route\Http\Pattern\Pattern;
$router->registerPattern(
'/products/:productId',
function ($matches)
{
// DO SOMETHING WITH: $matches['productId']
},
'GET'
)->setPlaceholder('productId', Pattern::DIGITS);
视图
很多时候,你的控制器操作很可能会返回视图。让我们了解一下视图是如何加载和使用来生成HTML响应的。
一个简单的视图
views/templates/default.php
这是一个简单的视图,包含页面标题和一些页面内容。假设它放在views/templates/default.php
中。(默认视图加载器在views/
内部查找视图。)
<!doctype html>
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
<?php echo $pageContent; ?>
</body>
</html>
src/Controller/SimpleController.php
这个视图可以这样加载到一个简单的控制器中。
namespace App\Controller;
use App\Controller\Controller;
class SimpleController extends Controller
{
public function index ()
{
return $this->viewLoader->load(
'templates/default',
[
'title' => 'Page Title!',
'pageContent' => 'This is some page content.',
]
);
}
}
生成的响应
请注意,viewLoader->load()
方法接受两个参数。第一个是视图文件的相对路径,相对于views/
目录。第二个是要注入到视图中的变量关联数组,键是它在视图中的名称。SimpleController::index()
方法将生成以下响应
<!doctype html>
<html>
<head>
<title>Page Title!</title>
</head>
<body>
This is some page content.
</body>
</html>
嵌套视图
视图也可以被加载并插入到其他视图中。
views/simple.php
<h1><?php echo $heading; ?></h1>
<p><?php echo $information; ?></p>
src/Controller/SimpleController.php
让我们更新我们的SimpleController::index()
方法,将其视图插入到templates/default.php
中。
namespace App\Controller;
use App\Controller\Controller;
class SimpleController extends Controller
{
public function index ()
{
$innerView = $this->viewLoader->load(
'simple',
[
'heading' => 'Simple Page Heading',
'information' => 'Some info about the page.',
]
);
return $this->viewLoader->load(
'templates/default',
[
'title' => 'Page Title!',
'pageContent' => innerView,
]
);
}
}
生成的响应
<!doctype html>
<html>
<head>
<title>Page Title!</title>
</head>
<body>
<h1>Simple Page Heading</h1>
<p>Some info about the page.</p>
</body>
</html>
依赖注入
依赖注入容器将依赖抽象化,从而使得代码更加灵活。容器(LiftKit\DependencyInjection\Container\Container
的一个实例)是连接应用程序的胶水。
依赖注入配置位于config/dependency-injection/
。默认情况下,那里有几个依赖注入配置文件。
规则
依赖注入容器的最基本单元是规则。规则是定义如何创建对象并将该操作映射到字符串标识符的回调函数。按照惯例,用户使用 StudlyCase 并用 .
作为“命名空间”分隔符。
一个简单的规则
这里是一个创建我们上面定义的App\Controller\SimpleController
的简单规则。请注意,回调函数的第一个参数总是容器本身。
use LiftKit\DependencyInjection\Container\Container;
use App\Controller\SimpleController;
$container->setRule(
'App.Controller.SimpleController',
function (Container $container)
{
return new SimpleController($container);
}
);
现在可以通过调用以下内容创建一个新的SimpleController
实例
$container->getObject('App.Controller.SimpleController');
在控制器中使用容器
容器被传递到所有控制器的构造函数中。它可以在任何控制器中使用,如下所示
$this->container->getObject('App.Controller.SimpleController');
依赖于其他规则的规则
规则可以使用其他规则。
use LiftKit\DependencyInjection\Container\Container;
use App\Parts\Engine;
use App\Vehicle\Car;
$container->setRule(
'App.Engine',
function ()
{
return new Engine();
}
);
$container->setRule(
'App.Car',
function (Container $container)
{
return new Car(
$container->getObject('App.Engine')
);
}
);
更多信息
有关依赖注入容器的更多信息,可以在GitHub上找到。
模块
模块控制配置文件的加载和应用程序的一般引导。模块对象扩展LiftKit\Module\Module
。应用程序的主要模块对象是App\Module\App
,它扩展了App\Module\Module
。
配置文件类型
存在几种配置文件类型,它们具有内置的加载实用方法(在App\Module\Module
中定义)。
loadDependencyInjectionConfig()
此方法用于加载依赖注入配置文件。按照惯例,这些文件位于config/dependency-injection/
。应用程序的依赖注入容器作为$container
注入到这些文件中。
loadSchemaConfig()
此方法用于加载数据库模式配置文件。按照惯例,这些文件位于config/database/schema/
。一个数据库模式对象(LiftKit\Database\Schema\Schema
的实例)作为$schema
注入到这些文件中。有关LiftKit数据库库的更多信息,请参阅GitHub。
loadRouteConfig()
此方法用于加载路由配置文件。按照惯例,这些文件位于config/routes/
。一个路由器(LiftKit\Router\Http
的实例)作为$router
注入到这些文件中,以及依赖注入容器作为$container
。
loadModule()和addSubModule()
此方法用于加载其他模块(LiftKit\Module\Module
的实例)作为应用程序的子模块,将它们的函数暴露给应用程序。这些通常位于通过composer安装的外部存储库中。每个子模块应公开一个PHP文件,该文件创建了模块对象并返回它。loadModule()
假定这些文件位于vendor/
文件夹中。它require
该PHP文件,并将返回的模块对象附加为应用程序的子模块。
例如,iris/iris
模块文件位于vendor/iris/iris/iris.php
,而iris/content
模块文件位于vendor/iris/content/content.php
。以下是一个加载并添加这两个模块作为子模块的App\Module\App
类的示例。
<?php
namespace App\Module;
class App extends Module
{
protected function loadModules()
{
$this->addSubModule(
'Iris',
$this->loadModule('iris/iris/iris')
);
$this->addSubModule(
'Iris.Content',
$this->loadModule('iris/content/content')
);
}
}
加载您自己的配置文件
假设您在config/dependency-injection/products.php
创建了一个新的依赖注入配置文件。以下是一个加载该文件的App\Module\App
类的示例。注意extend()
方法。
<?php
namespace App\Module;
class App extends Module
{
// ...
protected function extend ()
{
$this->loadDependencyInjectionConfig('dependency-injection/products');
}
}
模型和与数据库交互
Iris使用LiftKit的数据库库。您可以在GitHub上找到更多信息。一个简单的模型示例可以在iris/store
扩展中的联系人模型中找到这里。