We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Handling request with "application/json" Content-Type header

I would like to retrieve JSON raw params from POST request in my controller using $this->request->getPost("foo"); In order to achieve this I wrote a simple middleware class that is triggered on "dispatch:beforeExecuteRoute" event:

$di->set('dispatcher', function() use ($di) {
    $eventsManager = $di->getShared('eventsManager');
    $eventsManager->attach('dispatch:beforeExecuteRoute', new ContentNegotiationPlugin());

    $dispatcher = new Dispatcher();
    $dispatcher->setEventsManager($eventsManager);
    return $dispatcher;
}
class ContentNegotiationPlugin extends Plugin
{
    public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        $contentType = $this->request->getHeader('Content-Type');
        $contentType = $_SERVER['CONTENT_TYPE'];
        if ($contentType === 'application/json') {
            $rawBody = $this->request->getJsonRawBody(true);
            // inject params in the request
        }
    }
}

I have two questions:

  • Why $this->request->getHeader("Content-Type"); returns an empty string whereas $_SERVER["CONTENT_TYPE"] returns "application/json"?
  • Is there a way to inject $rawBody into the request, something like $this->request->setPost($rawBody);?

try

$this->request->getHeader('CONTENT_TYPE');
edited Dec '14

There is no explicit function for second question in zephir code of version 2 of Phalcon.

The only thing I can imagine is this

$rawBody = $this->request->getJsonRawBody(true);

foreach ($rawBody as $key => $value) {
    $_REQUEST[$key] = $value;
}

I've not tested this and I'm not sure what you want to achieve with this.

I'm not sure what you want to achieve with this.

Have a look at this thread: https://stackoverflow.com/a/12008719/1170998

Whether you send a POST request to your server with form-data, x-www-form-urlencoded or json data, express.js framework is able to parse the content using "bodyParser" middleware and populate req.body object with the appropriate content. The controller is therefore "request content type" agnostic and only works with req.body object.

Without this middleware I'm trying to develop, I'd be forced to check in every action for every controller if the post data has to be retrieved with $this->request->getJsonRawBody(); or with $this->request->getPost(), this would horrific. I want a single endpoint in my controller to retrieve POST data, whether the data were JSON encoded, urlencoded, etc... This might not be the best way to handle it though, any thoughts about this will be appreciated.

The method is to use getBestAccept() in request object:

    $bestAccept = $request->getBestAccept();
    if (is_string($bestAccept)) {
        $bestAccept = [$bestAccept];
    }
    $acceptsJson = (in_array('application/json', $bestAccept));

Hi @Batiste Costa did you found a solution for a single getPost whatever the content type is coming?

Have a look here : https://github.com/baptistecosta/mon-partenaire-phalcon/blob/master/app/module/api/plugin/BodyParser.php

This doenst work, i can have a POST/PATCH/DELETE, etc.. request. Also the value in the variable $_POST, does not persist.

Hi, does anyone have found a solution about this?



10.1k

I do this in my middleware

public function beforeExecuteRoute(Event $event, Micro $application)
    {
        $contentType = $this->request->getHeader('Content-Type');
        if (strpos($contentType, 'application/json') !== false) {
            $rawBody = $this->request->getJsonRawBody(true);
            if ($this->request->isPost()) {
                foreach ($rawBody as $key => $value) {
                    $_POST[$key] = $value;
                }
            }
        }
    }

Hi, i see you from Brazil, so i been write to you in Portuguese to better knowledge and guidance. The blunders 500 it is due to the fact you do not begin the elegance Membros in the code.