我正在为我的应用程序使用slim framework。
我需要建议如何实现为每个请求生成唯一ID或请求ID的过程,然后在响应中显示该唯一ID。
我的目的基本上是为每个请求提供一个唯一的id,并将该id保存在数据库中,最后将带有已处理数据的id显示给用户,这样用户可以在下次查询该ID时。
到目前为止我所理解的是,我应该通过使用中间件来实现这一点。
我创建了一个处理数据的函数,比如说:在课堂上的processed_data。
我的路线是:
$app->group('/products', function() {
new \Products($this);
});
class Products
{
public function __construct($app)
{
$app->map(['GET','POST'], '/processed_data', [$this, 'processed_data']);
$c = $app->getContainer();
}
public function processed_data($request, $response, $next){
$data = array('name' => 'Bob', 'age' => 40);
/* I need to append $data in $response or in any container,
instead of writting here using write() method so that I
can use my $data in middleware for final processing or
simply say adding a unique id with this $data.*/
return $response;
}
}
我创建的中间件是:
class SendStandardResponse
{
public function __construct(){}
public function get_standard_request($request, $response, $next) {
// here I saved the request in the database
/*I want here to generate a unique id say : XXXXXX .
I am not sure where to append this unique id, either in
request or response or container. */
return $request;
}
/**
* recode_Response
*/
public function send_stardard_esponse($request, $response, $next) {
// here I saved the response in the database
/* get the output data from the processed_data function and add the unique id to response .
And finally send the response with $data and unique id by merging /
$data = array('name' => 'Bob', 'age' => 40, 'requestid' => 'xxxxxx');
and send it with response
*/
return $response;
}
public function __invoke($request, $response, $next)
{
$this->get_standard_request($request, $response, $next);
$response = $next($request, $response);
$this->send_stardard_esponse($request,$response, $next);
return $response;
}
}
答案 0 :(得分:1)
您绝对正确地希望使用中间件来实现它。 但是,我建议您不要使用一个中间件,而是两个:一个用于生成ID并将ID附加到请求对象,另一个(在操作后调用)用于存储响应和相关ID。这将使您的代码更易于阅读和维护。只需将ID保留为请求属性。
可能是这样的:
<?php
/**
* This middleware generates and appends unique ID
*/
class IdHandlingMiddleware
{
/**
* Object constructor
*
* We're passing generator as argument so that
* ID generation logic - however simple it is
* is encapsulated in a separate class.
*/
public function __construct(IdGenerator $generator)
{
$this->IdGenerator = $generator;
}
/**
* Invoke middleware
*
* Generate ID, add it to response attributes and
* invoke next callable.
*
* Note it's throwing an exception if ID generator failed.
* I don't know how critical this ID system for you is.
*
*/
public function __invoke($request, $response, $next)
{
if ($id = $this->IdGenerator->generateUniqueId()) {
$request = $request->withAttribute('uniqueId');
} else {
throw new \Exception('Failed to generate unique ID');
}
return $next($request, $response);
}
}
/**
* This class records response and associated ID
*/
class ResponseRecordingMiddleware
{
/**
* Again, let's inject some kind of recorder,
* so we don't mix persistence layer and application layer.
* Keep things separated.
*/
public function __construct(Recorder $recorder)
{
$this->recorder = $recoder;
}
/**
* Record the response.
*
* Note I pass two arguments to Recorder::record:
* - response object
* - request ID that is contained as request attribute.
*/
public function __invoke($request, $response, $next)
{
$response = $next($request, $response);
$this->recorder->record($response, $request->getAttribute('uniqueId'));
return $response;
}
}
/**
* And don't forget to register these middlewares.
* Note the order of adding.
*/
$app->add(ResponseRecordingMiddleware::class)->add(IdHandlingMiddleware::class);