h4d / leveret
PHP 微框架,用于构建 Web 应用程序和 API
Requires
- php: >=5.5.9
- h4d/i18n: ^1.0.4
- h4d/patterns: ^1.0.7
- h4d/template: ^1.0
- psr/log: ~1.0
- retrinko/ini: ^1.0
Requires (Dev)
- phpunit/phpunit: ^4.8
- dev-master
- v1.4.0
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.1.18
- v1.1.17
- v1.1.16
- v1.1.15
- v1.1.13
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feature/view-renderers
- dev-dev
This package is not auto-updated.
Last update: 2024-09-15 00:17:04 UTC
README
这是一个微框架,允许以简单的方式创建 HTTP 应用程序(类似 slim, silex 等)。
$app = new Application();
$app->registerRoute('GET', '/hello/:string')
->setAction(
function ($name) use ($app)
{
$app->getResponse()->setBody('Hello '.$name);
});
$app->run();
如何安装?
要使用 composer 安装 leveret,您需要执行以下命令
$ composer require h4d/leveret
注意: 必须包含托管在私有仓库中的依赖项仓库的所有数据。例如,由于 h4d/leveret 依赖于包 h4d/template,因此还需要包含该仓库的数据(与在 Packagist 上发布的包不同,composer 不能自动解析)。
如何使用?
配置文件
为了使应用程序正常工作,需要创建一个配置文件,其路径将作为参数传递给 \H4D\Leveret\Application 的构造函数。如果未向构造函数传递配置文件,则将实例化一个具有默认配置值的应用程序。
以下表格显示了默认配置文件的内容。
[application]
; Application name
name = NoNamedApp
; Application environmnet: production, development.
environment = production
; Application root directory.
path = ../app
; Default content type for responses: text/html, application/json, etc.
defaultContentType = text/html
; Error handler: internal Application static method name.
errorHandler = errorHandler
; Default input filter type (@see https://php.ac.cn/manual/en/filter.filters.sanitize.php)
; 516: FILTER_UNSAFE_RAW
; 522: FILTER_SANITIZE_FULL_SPECIAL_CHARS
; 513: FILTER_SANITIZE_STRING
defaultInputFilterType = 516
; Register routes defined in [routes] section (values: true|false).
registerRoutesDefinedInConfigFile = true
[views]
; View templates directory
path = ../app/views
[routes]
; Example: Call appplication method
appInfo[pattern] = "/app/info"
appInfo[method] = "GET"
appInfo[callback] = "renderAppInfo"
; Example: Call controller/action
;status[pattern] = "/app/status"
;status[method] = "GET"
;status[callback] = "Your/Controller/ClassName::controllerMethod"
注意: 如果配置文件中指定的路径是相对路径,则它们将相对于服务器根目录。
实例化应用程序
/** @var \H4D\Leveret\Application $app */
$app = new \H4D\Leveret\Application($configFilePath);
注册路由
路由通过 registerRoute($method, $routePattern) 方法进行注册。
第一个参数将指示 HTTP 方法(GET、POST、DELETE 等)。第二个参数是必须处理的路由表示。
路由表示支持“通配符”。通配符字符串的格式如下::(类型)名称,其中 类型 是变量的类型(int、float、string 等),名称 是变量的名称/别名。通配符字符串中指定类型的部分是可选的,如果没有指定类型,则变量将被映射为字符串类型。
目前支持的通配符类型包括
- word:一个单词 ([\w] )*。
- string:任何由 a-z、0-9、大写字母、下划线和空格组成的字符串 ([a-zA-Z0-9- _]*)。
- integer 或 int:带有可选符号的整数 ([-+]?[0-9]*)。
- float 或 number:带有可选符号的小数 ([-+]?[0-9]*[.]?[0-9]+)。
“通配符”示例
- :(string)server:表示一个名为 "server" 的字符串类型的变量。
- :server:与前面的例子等价。省略通配符字符串中定义类型的部分,将变量 "server" 映射到 "string" 类型。
- :(int)age:表示一个名为 "age" 的整型变量。
- :(float)price:表示一个名为 "price" 的浮点型变量。
路由表示示例
/add/:(float)num1/:(float)num2
/hello/:name
每个路由必须通过 setAction($clousure) 方法分配一个动作,如下所示
// Action with multiple params.
$app->registerRoute('GET', '/add/:(float)num1/:(float)num2')
->setAction(
function ($num1, $num2) use ($app)
{
$result = $num1 + $num2;
$app->getLogger()->notice(sprintf('Result: %f', $result), ['num1' => $num1,
'num2' => $num2,
'result' => $result]);
$app->getResponse()->setBody($result));
});
如果想要向闭包传递其他变量,甚至整个应用程序,可以通过使用 use 来实现。
另一种将动作分配给路由的方法是使用控制器。可以通过 useController($controllerClassName, $controllerClassMethod) 方法设置控制器/动作对,其中第一个参数是控制器类的名称,第二个参数是在调度期间要执行的方法的名称。
以下是一个将控制器/动作对分配给路由的示例。
$app->registerRoute('GET', '/add/:(float)num1/:(float)num2')->useController('MathController', 'add');
对于每个路由,可以选择性地关联多个预分发和后分发的动作。为此,提供了addPreDispatchAction($callable)和addPostDispatchAction($callable)方法。默认情况下,将路由和相关应用作为参数传递给“callable”,这样就可以访问应用中的任何子组件(记录器、请求、响应等)。
在下面的示例中,添加了一个预分发动作,该动作修改请求参数,将所有字符串类型的参数转换为大写。
$app->registerRoute('GET', '/hello/:name')
->setAction(
function ($name) use ($app)
{
$app->getView()->addVar('name', $name);
$app->render('hello.phtml');
})
->addPreDispatchAction(
function ($route, $app)
{
$newParams = array();
/** @var \H4D\Leveret\Application\Route $route */
foreach($route->getParams() as $key => $value)
{
$newParams[$key] = is_string($value) ? strtoupper($value) : $value;
}
$route->setParams($newParams);
})
在配置文件中注册路由
可以从配置文件中注册简单路由。
要激活在配置文件中定义的路由的注册,需要将配置值registerRoutesDefinedInConfigFile定义为true
registerRoutesDefinedInConfigFile = true
路由配置在[routes]部分,可以是两种类型之一
- 指向Controller/Action的路由。
- 指向应用类方法的路由。
指向Controller/Action的路由定义
[routes]
; Example: Define a route named "status" dispatched by a controller/action
status[pattern] = "/example/route"
status[method] = "GET"
status[callback] = "Your/Controller/ClassName::controllerMethod"
指向应用类方法的路由定义
[routes]
; Example: Define a route named "info" dispatched by an app's method
info[pattern] = "/example/route"
info[method] = "GET"
info[callback] = "anAppMethod" ;; Method's name of your app class
请求验证
当在应用中注册路由时,可以为预期接收的每个参数添加必要的验证器。可用于此目的的方法是addRequestConstraints($paramName, [Constraints]),它接受一个字符串作为第一个参数,用于标识要验证的参数名称,以及一个规则(Constraint)或规则集(Constraints)数组,该参数必须遵守。
在下面的示例中,为username和alias参数添加了多个验证规则。
$this->registerRoute('POST', '/admin/deploy-request')
->addRequestConstraints('username', [new Required(), new NotBlank(), new Email()])
->addRequestConstraints('alias', [new Required(), new NotBlank(),
new Length(array('min'=>3, 'max'=>100))])
->useController('AdminController', 'deployRequest');
验证规则必须是符合H4D\Leveret\Validation\ConstraintInterface接口的类的实例。如果需要不符合该接口的验证规则,可以创建适配器,例如H4D\Leveret\Validation\Adapters\H4DConstraintAdapter,它允许使用项目h4d/validator中定义的验证规则,或者H4D\Leveret\Validation\Adapters\SymfonyConstraintAdapter,它允许使用项目https://symfony.com.cn/doc/current/reference/constraints.html中的验证规则。
以下示例展示了如何使用适配器来使用H4D验证规则。
$app = new Application();
$app->registerRoute('GET', '/hello/:(string)name')
->addRequestConstraints('name', new H4DConstraintAdapter((new Enum())->setOptions(['paco', 'maria'])))
->setAction(
function ($name) use ($app)
{
$isValid = $app->isValidRequest();
if (!$isValid)
{
throw new \Exception($app->getRequestConstraintsViolationMessagesAsString());
}
$app->getResponse()->setBody('Hello '.$name);
});
$app->run();
以下示例展示了如何使用Symfony验证规则。
$app = new Application();
$app->registerRoute('GET', '/hello/:(string)name')
->setRequiredParam('name')
->addRequestConstraints('name', [new SymfonyConstraintAdapter(new Required()),
new SymfonyConstraintAdapter(new NotBlank())])
->setAction(
function ($name) use ($app)
{
$isValid = $app->isValidRequest();
if (!$isValid)
{
throw new \Exception($app->getRequestConstraintsViolationMessagesAsString());
}
$app->getResponse()->setBody('Hello '.$name);
});
$app->run();
从Leveret的Application对象中,可以通过以下方法获取请求验证结果的信息
- isValidRequest($request, $constraints):返回布尔值(true:一切正常,false:有验证错误)
- getRequestConstraintsViolations():返回一个关联数组,包含ConstraintViolationList中的验证错误信息。
- getRequestConstraintsViolationMessages():返回一个关联数组,包含所有错误信息的对象。
- getRequestConstraintsViolationMessagesAsString($separator):返回一个包含错误信息的字符串。
有关这些方法的更多信息,请参阅它们的签名。
必需参数
要定义特定路由的哪些参数是必需的,提供了两种方法
- setRequiredParam(string $paramName):允许独立设置一个参数为必需。
- setRequiredParams(array $paramsNames):允许一次性设置多个参数为必需。
使用示例
$this->registerRoute('POST', '/admin/deploy-request')
->setRequiredParam('username')
->addRequestConstraints('username', [new Required(), new NotBlank(), new Email()]);
请求自动验证
Levaret 允许配置参数验证是否以自动方式(在路由后程序之后)或手动方式进行。在自动模式下,可以定义何时进行请求验证,是在认证之后(如果需要)还是认证之前(如果需要)。
可以通过方法 setAutoRequestValidationMode($mode) 配置这三种模式。$mode 的可能值有:
- NO_VALIDATION: 不进行自动验证。
- VALIDATION_BEFORE_AUTH: 在认证程序之前自动进行验证。
- VALIDATION_AFTER_AUTH: 在认证程序之后自动进行验证。
对于每种模式,在 Application 类中都有定义的常量。
const AUTO_REQUEST_VALIDATION_MODE_NO_REQUEST_VALIDATION = 'NO_VALIDATION';
const AUTO_REQUEST_VALIDATION_MODE_REQUEST_VALIDATION_BEFORE_AUTH = 'VALIDATION_BEFORE_AUTH';
const AUTO_REQUEST_VALIDATION_MODE_REQUEST_VALIDATION_AFTER_AUTH = 'VALIDATION_AFTER_AUTH';
使用示例
$app = new Application(APP_CONFIG_DIR.'/config.ini');
$app->setAutoRequestValidationMode(Application::AUTO_REQUEST_VALIDATION_MODE_REQUEST_VALIDATION_BEFORE_AUTH);
POST|PUT|PATH|DELETE 参数过滤、查询参数和 URL
默认情况下,会对通过 POST、PUT、PATH、DELETE、查询参数或 URL 到达应用程序的所有参数应用过滤。默认应用的过滤器可以在应用程序的配置文件中通过字段 defaultInputFilterType 指定。该字段的值是一个整数,相当于 PHP 的某些标准过滤器([查看 PHP 文档] (https://php.ac.cn/manual/en/filter.filters.sanitize.php))。以下列出了 defaultInputFilterType 的常见值:
- 516 (FILTER_UNSAFE_RAW): 不过滤参数。
- 522 (FILTER_SANITIZE_FULL_SPECIAL_CHARS): 等同于 htmlspecialchars()。
- 513 (FILTER_SANITIZE_STRING): 过滤字符串中的标签。
可以使用方法 addRequestFilters($paramName, $filters) 对特定参数应用过滤器,其中 $paramName 是要过滤的参数的名称,$filters 是一个数组,包含符合接口 H4D\Leveret\Filter\FilterInterface(或接受一个值并返回过滤值的闭包)的对象。
示例
$this->registerRoute('POST', '/create/alias')
->addRequestFilters('alias', [new Filter1(), new Filter2(),
function($alias){return strtolower($alias)}]);
应用程序执行
方法 run() 负责路由请求并向客户端提供 HTTP 响应。
$app->run();
控制器
应用程序的控制器必须继承自 H4D\Leveret\Application\Controller 才能使用。
从控制器的任何方法中,都可以通过内部变量 $app 访问应用程序,并通过该对象访问 request、response、view 等。
基本控制器的示例
use H4D\Leveret\Application;
use H4D\Leveret\Application\Controller;
use H4D\Leveret\Http\Response\Headers;
class MathController extends Controller
{
/**
* Sobreescribo método init
*/
public function init()
{
// Especifico el layout que se utilizará para todas las acciones de este controller
$this->useLayout('layouts/main.phtml');
}
/**
* @param float $a
* @param float $b
*/
public function add($a, $b)
{
// Obtengo la vista y paso las variables necesarias.
$this->getView()
->addVar('title', sprintf('%s + %s', $a, $b))
->addVar('num1', $a)
->addVar('num2', $b)
->addVar('result', $a+$b);
// Especifico la pantilla que se va a emplear.
$this->render('add.phtml');
}
public function info()
{
// No uso vista, seteo directamente el cuerpo de la respuesta.
$this->getResponse()->setBody(phpinfo());
}
}
方法 init()
在控制器中,我们可以实现方法 init(),该方法将在实现它的控制器实例化时被调用。
- init(): 当实例化控制器时执行。
方法 preDispatch() 和 postDispatch()
在控制器中,我们可以实现具有特殊行为的方法 preDispatch() 和 postDispatch()。
- preDispatch(): 如果控制器中存在 preDispatch() 方法,则该方法将在路由注册表中的指定动作之前执行。
- postDispatch(): 如果控制器中存在 postDispatch() 方法,则该方法将在路由注册表中的指定动作之后执行。
其他有趣的方法
控制器有多个有用的方法,其中一些是
- getApp(): 返回 \H4D\Leveret\Application 的实例对象。
- getLogger(): 返回应用程序中注册的 Logger (LoggerInterface)。
- getRequest(): 返回正在处理的 Request 对象 (\H4D\Leveret\Http\Request)。
- getRoute(): 返回正在处理的 Route 对象 (\H4D\Leveret\Application\Route)。
- getResponse(): 返回 Response 对象 (\H4D\Leveret\Http\Response)。
- getView(): 返回 View 对象 (\H4D\Leveret\Application\View)。
- getLayout(): 返回用作主布局的 View 对象 (\H4D\Leveret\Application\View)。
- setView(View $view):设置应用程序的View对象。
- setLayout(View $view):设置用作应用程序布局的View对象。
- setResponse(Response $response):设置应用程序的Response对象。
- render(string $template):应用程序render(string $template)方法的快捷方式。
- isValidRequest():应用程序isValidRequest()方法的快捷方式。
- getRequestValidationErrorMessages():应用程序getRequestConstraintsViolationMessages()方法的快捷方式。
- getRequestValidationErrorMessagesAsString($separator):应用程序getRequestConstraintsViolationMessagesAsString()方法的快捷方式。
视图
当需要使用模板时,可以利用与应用程序关联的默认视图,通过相应的方法传递将被模板替换的变量(请参阅H4D\Leveret\Application\View.php)。
要指定要渲染的模板,将使用应用程序对象的render($template)方法。它接受一个参数,即模板文件的相对路径,该路径相对于视图的基本路径(在应用程序的配置文件中定义,在views/path部分)。
$app->render('add.phtml');
模板通常是phtml文件(尽管可以是任何其他类型)。
模板示例
<html>
<head>
<title><?php echo $title?></title>
</head>
<body>
<div style="text-align: center; font-size: 40pt; margin: 40px;">
<?php echo $num1; ?> + <?php echo $num2; ?> = <?php echo $result; ?>
</div>
</body>
</html>
部分视图
可以在其他视图中使用部分视图,方法如下
<div>
<?php echo $this->partial(APP_VIEWS_DIR.'/partials/test/test.phtml', ['nombre'=>'Pakito']);?>
</div>
部分视图“继承”了容器视图的所有方法和变量。
允许在部分视图内部使用部分视图。例如
在主视图
<div>
<?php echo $this->partial(APP_VIEWS_DIR.'/partials/test/partial.phtml', ['nombre'=>'Pakito']);?>
</div>
在 APP_VIEWS_DIR.'/partials/test/partial.phtml'
<h1>Partial</h1>
<p>
<?php echo $this->translate('Hola %s! Esto es un partial.', $nombre);?>
</p>
<?php echo $this->partial(APP_VIEWS_DIR.'/partials/test/internal.phtml');?>
在 APP_VIEWS_DIR.'/partials/test/internal.phtml'
<h2>Partial interno</h2>
<?php echo $this->translate('Hola %s! Soy un partial dentro de otro partial', $nombre);?>
如何在部分视图中解决变量名的问题?
- 如果变量在部分视图中定义,则使用该变量。
- 如果变量未在部分视图中定义,但在容器视图中定义,则使用容器视图中的变量。
- 如果变量既未在部分视图中定义,也未在容器视图中定义,则抛出渲染异常。
注意!内部部分视图不“继承”容器部分视图的变量,只继承容器视图的变量。
布局
布局是可以用作其他视图容器的视图。在所有布局中,都存在一个默认变量,名为$contents,在应用程序的渲染过程中,它将被其他视图的内容所替换。
要使用特定的布局,必须使用应用程序的useLayout($template)方法,其中$template是布局模板文件的相对路径,相对于应用程序视图的基本路径。
$app->useLayout('layouts/main.phtml');
$app->render('add.phtml');
事件
无论是应用程序还是Leveret的控制器,都实现了publisher模式,因此可以通过publish(Event $event)方法发布事件。
$app->publish($myEvent);
可以订阅尽可能多的应用程序事件,使用attachSubscriber(SubscriberInterface $subscriber)方法。
$app->attachSubscriber($mySubscriberOne);
$app->attachSubscriber($mySubscriberTwo);
如果需要取消订阅,请使用detachSubscriber(SubscriberInterface $subscriber)方法。
$app->dettachSubscriber($mySubscriberTwo);
控制器具有添加或删除监听器的方法。从控制器发布的所有事件都会传播到应用程序。
依赖注入/服务容器
Leveret包含一个非常简单的服务容器,支持以下类型
- 实例
- 可调用
- 键值对
- 资源
要在应用程序中注册服务,可以使用应用程序对象的registerService( string $serviceName, mixed $value, $singleton = false)方法。其中
- $serviceName:是要分配给服务的字符串名称。
- $value:是服务本身,可以是可调用、实例、资源或键值对。
- $singleton:仅当 $value 是可调用的并且只执行一次调用,后续调用返回相同返回值时使用。
为了获取已注册的服务,应用程序对象提供了 getService( string $serviceName) 方法,其中
- $serviceName:是我们先前已注册的服务名称。
与其他服务相关的有用方法有
- bool isServiceRegistered(string $serviceName):如果名为 $serviceName 的服务已注册,则返回 true 或 false。
- ServiceContainerInterface getServiceContainer():返回应用程序的服务容器。
- Application setServiceContainer(ServiceContainerInterface $serviceContainer):允许为应用程序设置服务容器。
Leveret 应用程序有一个注册服务的位置,那就是我们应用程序类中的 initServices() 方法。
将实例作为服务注册
示例:将 MyService 类的实例注册为应用程序的服务。
$app->registerService('ServiceName', new MyService());
将可调用项作为服务注册
示例:注册服务 'ServiceName'。当第一次调用 $app->getService('ServiceName') 时,将创建一个 MyService 的实例并返回。在后续调用中,将返回相同的 MyService 实例,不会再次执行可调用项的代码。
$app->registerService('ServiceName', function ()
{
$configFile = IniFile::load(APP_CONFIG_DIR . '/sample.ini');
$myService = new MyService($configFile);
return $myService;
}, true);
如果希望在每次调用 $app->getService('ServiceName') 时都创建不同的 MyService 实例,只需将 $singleton 参数值更改为 false 即可。
示例:注册服务 'ServiceName'。每次调用 $app->getService('ServiceName') 时,都将实例化一个新的 MyService 对象并返回。
$app->registerService('ServiceName', function ()
{
$configFile = IniFile::load(APP_CONFIG_DIR . '/sample.ini');
$myService = new MyService($configFile);
return $myService;
}, false);
注意:与注册实例相比,注册可调用项有一个重要的优势:如果未调用 $app->getService('ServiceName'),则不会执行对象实例化代码。因此,将服务作为可调用项注册可以减少应用程序的“启动”时间和内存消耗,因为只有在使用服务时才会创建新的实例,并且实例化将在运行时而不是在应用程序加载时进行。
将键值对作为服务注册
Leveret 允许以下方式注册键值对作为服务
$app->registerService('MyKey', 'MyValue');
将资源作为服务注册
与上述所有情况一样,为了在我们的应用程序中将资源(resource)注册为服务,我们将使用 $app->registerService( string $serviceName, resource $resuorce) 方法。
$app->registerService('MyResource', $myResource);
ACLs
Leveret 支持使用基本的 ACL(访问控制列表)。通过它们,我们可以根据我们定义的规则(必须符合 H4D\Leveret\Application\AclInterface 接口)限制对我们应用程序中某些组件的访问。
ACLs 的注册位置是我们应用程序类中的 initAcls() 方法。
可以注册针对路由和控制器/操作的 ACLs,为此提供了以下方法:
- registerAclForRoute(AclInterface $acl, string $routeName)
- registerAclForController(AclInterface $acl, string $controllerName, array $applyToActions = ['*'], array $excludedActions = [])
为路由注册 ACLs
为了为特定路由注册一个或多个 ACLs,我们必须使用应用程序的方法:registerAclForRoute(AclInterface $acl, string $routeName),其中
- $acl: 是一个必须遵守 AclInterface 接口的类实例。
- $routeName: 是我们分配给想要应用 ACL 的路由的名称。
ACLs 的控制器注册
我们可以使用以下应用程序方法注册应用于控制器或控制器中特定 action 的 ACLs: registerAclForController(AclInterface $acl, string $controllerName, array $applyToActions = ['*'], array $excludedActions = []),其中
- $acl: 是一个必须遵守 AclInterface 接口的类实例。
- $controllerName: 是控制器的完整名称(命名空间 + 类名)。
- $applyToActions: 是一个字符串数组,可以用来指定将 ACL 应用到哪个控制器中的 action 列表。默认情况下,此数组的值为 ['*'],表示 ACL 将应用于控制器中的所有 action。
- $excludedActions: 是一个字符串数组,用来指定不希望应用 ACL 的 action(相当于 action 的白名单)。
示例:将注册为服务的 ACL AdminLoggedInRequired 应用于控制器 MyAppp\Controller\AdminController。
$this->registerAclForController($this->getService(AdminLoggedInRequired::class),
'MyAppp\Controller\AdminController');
完整示例
<?php
use H4D\Leveret\Application;
use H4D\Leveret\Http\Response;
use H4D\Leveret\Http\Response\Headers;
use H4D\Logger;
require_once('../app/bootstrap.php');
/** @var Application $app */
$app = new Application(APP_CONFIG_DIR.'/config.ini');
////////////////////////////////////////////////////////////////////////////////////////////////////
// INI: Register routes and actions ////////////////////////////////////////////////////////////////
// Simple action without params returning html contents using a template.
$app->registerRoute('GET', '/')
->setAction(
function () use ($app)
{
$app->getLogger()->notice('It works!');
$app->render('default.phtml');
});
// Action with one param, multiple predispatch actions and one postdispatch action returning html
// contents using a template.
$app->registerRoute('GET', '/hello/:name')
->setAction(
function ($name) use ($app)
{
$app->getLogger()->notice('Hello', array('name' => $name));
$app->getView()->addVar('name', $name);
$app->render('hello.phtml');
})
->addPreDispatchAction(
function ($route, $app)
{
$newParams = array();
/** @var \H4D\Leveret\Application\Route $route */
foreach($route->getParams() as $key => $value)
{
$newParams[$key] = is_string($value) ? strtoupper($value) : $value;
}
$route->setParams($newParams);
})
->addPreDispatchAction(
function ($route, $app)
{
$newParams = array();
/** @var \H4D\Leveret\Application\Route $route */
foreach($route->getParams() as $key => $value)
{
$newParams[$key] = is_string($value) ?
'"' . $value . '"' : $value;
}
$route->setParams($newParams);
})
->addPostDispatchAction(
function ($route, $app)
{
/** @var Application $app */
$app->getResponse()->setStatusCode('404');
}
);
// Action with multiple params returning JSON content type.
$app->registerRoute('GET', '/add/:(float)num1/:(float)num2')
->setAction(
function ($num1, $num2) use ($app)
{
$result = $num1 + $num2;
$app->getLogger()->notice(sprintf('Result: %f', $result), array('num1' => $num1,
'num2' => $num2,
'result' => $result));
// Change response headers.
$app->getResponse()->getHeaders()->setContentType(Headers::CONTENT_TYPE_JSON);
$app->getResponse()->setBody(json_encode(array('num1' => $num1,
'num2' => $num2,
'result' => $result)));
})
->addPreDispatchAction(function ($route, $app)
{
/** @var Application $app */
if ($app->getRequest()->hasAuth())
{
$user = $app->getRequest()->getAuthUser();
$pass = $app->getRequest()->getAuthPassword();
$app->getLogger()->debug(sprintf('User: %s, Pass: %s', $user, $pass));
}
});
// END: Register routes and actions ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// Run the application!
$app->run();