在Slim框架3中为请求分配唯一ID的正确方法是什么?

时间:2016-12-24 05:11:22

标签: slim

我正在为我的应用程序使用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;
        }
    }

1 个答案:

答案 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);