Search code examples
phpmiddlewareslim-3

response->getBody() is empty in slim3 php framework


I'm having trouble with this slim3 php code. On function createErrorReponse function, $response->getBody() is null or empty. Php complains the following error below. As you can see the getBody() size is empty and hence write won't work on it. The same line works in other functions though. HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 0 Fatal error: Call to a member function withHeader() on a non-object in /home/ubuntu/webapp/middleware/authmodule.php on line 16

<?php
class AuthenticationMiddleware
{
        public function isAuthenticated($userid, $authorization)
        {
                //do data validation here
                return false;
        }

        public function createErrorResponse($code, $msg, $response)
        {
                echo $response;
                echo $response->getBody()->getSize();
                $response = $response->getBody()->write(json_encode('holla'));
                $response = $response->withHeader('Content-Type', 'application/json; charset=utf-8');
                return $response;
        }

        public function __invoke($request, $response, $next)
        {
                $userid = $request->getHeaderLine('userid');
                $authorization = $request->getHeaderLine('Authorization');
                if($this->isAuthenticated($userid, $authorization))
                {
                        $response = $next($request, $response);
                }
                else
                {
                        $msg = 'You are unauthenticated. Please login again';
                        $code = 400;
                        $response = $this->createErrorResponse($code, $msg, $response);
                }
                return $response;
        }
}

Solution

  • Thanks for the heads up about the bug report and fix. I feel the need to give an answer to this question though, just in case you haven't ditched PHP and Slim framework altogether. Hopefully, it will be of help to someone else.

    My approach to this would be:

    <?php
    
    use Slim\Http\Request;
    use Slim\Http\Response;
    
    class AuthenticationMiddleware {
    
        public function isAuthenticated($userid, $authorization) {
            //do data validation here
            return false;
        }
    
        public function createErrorResponse($code, $msg, Response $response) {
            return $response->withStatus($code)
                ->withHeader('Content-Type', 'application/json;charset=utf-8')
                ->withJson($msg);
        }
    
        public function __invoke(Request $request, Response $response, $next) {
            $userid = $request->getHeaderLine('userid');
            $authorization = $request->getHeaderLine('Authorization');
            if(!$this->isAuthenticated($userid, $authorization)) {
                $msg = 'You are unauthenticated. Please login again';
                $code = 400;
                $this->createErrorResponse($code, $msg, $response);
            } else {
                $response = $next($request, $response);
            }
            return $response;
        }
    }
    

    Let me just say this. I would abstract a few stuff here in this code so I don't end up repeating myself. I see you repeating:

    public function createErrorResponse($code, $msg, Response $response) {
        return $response->withStatus($code)
            ->withHeader('Content-Type', 'application/json;charset=utf-8')
            ->withJson($msg);
    }
    

    In all your middleware and perhaps, in your routes. Hope this sets someone on the right track.