Get raw POST data in Laravel

I recently stumbled upon an interesting problem when trying to retrieve the raw POST body in Laravel. This happened when I was sending POST/PUT requests from AngularJS to a REST API that was built with Laravel. I did a lot of trial and error before I figured out the problem.

To start of with we take a look at how we get the raw POST data in PHP. It’s a fairly simple command:

<?php
$rawPostData = file_get_contents("php://input");

The php://input is an I/O stream that you can read the raw POST data from. What is interesting though is that it can only be read once. And this is what caused me not being able to fetch it in this simple matter.

Why is that?

If you are familiar with Laravel you probably know that a lot of its core is built upon Symfony components, and the HTTP request handler is one of those components. If we dig in to the class Symfony\Component\HttpFoundation\Request we find this interesting line:

<?php
$this->content = file_get_contents('php://input');

Now you remember what I said about the I/O stream, right? I will repeat that, it can only be read once. Since the Symfony component reads the I/O stream, it’s empty after that. This results in that you can not access straight in your application with the simple approach I wrote before.

What then?

Lucky for us, the request instance is accessible through the Request facade in Laravel. The request instance then have the raw POST data set as its content.

<?php
// First we fetch the Request instance
$request = Request::instance();

// Now we can get the content from it
$content = $request->getContent();

Now we have the raw POST data in $content, simple as that.

  • Hello, just to let you know that as of PHP 5.6 you can call php://input multiple times and get the data – I have just tested it here on localhost and works fine 🙂

    Note: Prior to PHP 5.6, a stream opened with php://input could only be read once; the stream did not support seek operations.
    http://php.net/manual/en/wrappers.php.php

    • Niklas Modess

      Cool, good to know! However the feature sounds a bit shaky, not working for PUT requests for example. I wonder how the HTTP packages handles this, if you do further research let me know!