AngularJS HTTP post to PHP and undefined

angularjs .post() defaults the Content-type header to application/json. You are overriding this to pass form-encoded data, however you are not changing your data value to pass an appropriate query string, so PHP is not populating $_POST as you expect.

My suggestion would be to just use the default angularjs setting of application/json as header, read the raw input in PHP, and then deserialize the JSON.

That can be achieved in PHP like this:

$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$email = $request->email;
$pass = $request->password;

Alternately, if you are heavily relying on $_POST functionality, you can form a query string like [email protected]&password=somepassword and send that as data. Make sure that this query string is URL encoded. If manually built (as opposed to using something like jQuery.serialize()), Javascript's encodeURIComponent() should do the trick for you.


I do it on the server side, at the begining of my init file, works like a charm and you don't have to do anything in angular or existing php code:

if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST))
    $_POST = json_decode(file_get_contents('php://input'), true);

In the API I am developing I have a base controller and inside its __construct() method I have the following:

if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true));
}

This allows me to simply reference the json data as $_POST["var"] when needed. Works great.

That way if an authenticated user connects with a library such a jQuery that sends post data with a default of Content-Type: application/x-www-form-urlencoded or Content-Type: application/json the API will respond without error and will make the API a little more developer friendly.

Hope this helps.


Because PHP does not natively accept JSON 'application/json' One approach is to update your headers and parameters from angular so that your api can use the data directly.

First, Parameterize your data:

data: $.param({ "foo": $scope.fooValue })

Then, add the following to your $http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 }, 

If all of your requests are going to PHP the parameters can be set globaly in the configuration as follows:

myApp.config(function($httpProvider) {
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});