How to access a variable passed from AngularJS via http in PHP? - php

I am passing an object into a PHP script like this:
$http({
method: 'POST',
url: 'updateCoins.php',
data: {flips: $scope.data.flips, error: $scope.data.pe},
})
In my PHP script I tried:
$data = file_get_contents("php://input");
and
$data = json_decode(file_get_contents("php://input"));
I then tried echoing back the received value like this:
echo $data.flips
or
echo $data[flips]
or
echo $data->flips
I keep on getting either a blank result or the word "flips" back. How do I access those variables?

If the data was sent JSON-encoded, then it would make sense to json_decode(). I suspect that your data is x-www-form-urlencoded (eg: name=john&age=7). In this case, PHP parses it into the $_POST array for you. If you wish to do it on your own, and handle either case, you could do something like:
// Read content-type to determine whether it's JSON data
$type = $_SERVER["CONTENT_TYPE"];
$content = file_get_contents('php://input');
if(strpos($type,'json') > -1):
$data = json_decode($content, true);
else:
parse_str($content, $data);
endif;
print_r($data);
You can always visually inspect the data with echo file_get_contents('php://input');

Php won't grab the posted data from $_POST if the post is formatted in json. You can serialize the post data and submit it thusly
var data = 'flips='+$scope.data.flips+'&error='+$scope.data.pe;
$http({
method: 'POST',
url: 'updateCoins.php',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: data
});
OR you can do like BeetleJuice recommended. In my application I just do the following so that the rest of the code is uninterrupted.
if (empty($_POST) && file_get_contents('php://input')!==""){
$_POST = json_decode(file_get_contents('php://input'), true);
}
at which point you can access it with $_POST['flips'] and $_POST['error']

Related

I keep getting this Fatal Error: Cannot use object of type stdClass as array

I've been banging my head against a wall with this simple comunication between javascript and php.
I have an HTML form which asks the user to input two numbers. It should send those two numbers as JSON to the server (process.php). In the server, it should add the two numbers and send the result back to the JavaScript. After that, it would print the result on the HTML file.
javascript.js
$(document).ready(function(){
$('#calcular').click (function(e){
e.preventDefault();
var numerosJSON = JSON.stringify($('#myForm').serializeArray());
$.ajax({
url: '/process.php',
type:'post',
data: numerosJSON,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
contentType: 'application/json',
success: function(soma){
//shows result in a div in the html file
$('#out').text(soma);
}
});
});
})
process.php
$json = file_get_contents('php://input');
$numeros = json_decode($json, true);
$fst = $_POST['first'];
$snd = $_POST['second'];
$soma = $fst + $snd;
header('Content-Type: application/json, charset=utf-8');
echo json_encode($soma);
It does send the request, but I always get an error :
Fatal Error: Cannot use object of type stdClass as array
Can you guys lend me a hand on this? It's driving me crazy!
In your posted PHP code you decode the received JSON object but don't use it, rather you try to retrieve the values from $_POST. After you decode the object, you will have one array element containing name and value children per serialized input. If you want to access these elements by name, you'll need to loop over the received and decoded array via array_map() or while/for. For simplicity I used access by array index in my sample.
<?php
$json = file_get_contents('php://input');
$numeros = json_decode($json, TRUE);
$fst = $numeros[0]["value"];
$snd = $numeros[1]["value"];
$soma = $fst + $snd;
header('Content-Type: application/json, charset=utf-8');
echo json_encode($soma);

Why does RESTAPI's POST Method work in POSTMAN but works differently using AJAX?

Why is it that if I am using Postman, I dont need to include if ($_POST) { '' } else { $_POST = json_decode(file_get_contents('php://input'), true);}
It works differently as If I were to send it from AJAX, but why?
Why doesn't Postman requres json_decode(file_get_contents('php://input'), true);
Ajax code
$.ajax({
url: "http://localhost/WEP/RESTAPI/php.php?api",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json",
success: function(data) {
window.alert("Friend added! "+$name.val()+' '+$email.val());
},
error: function() {
alert("Error");
}
});
PHP
elseif ($srequest == 'POST'){
if ($_POST) {
'';
} else {
$_POST = json_decode(file_get_contents('php://input'), true);
}
$id = $_POST['id'];
$name = $_POST['name'];
$email = $_POST['email'];
//...mysqli connect,query
Your Ajax has been written to send a POST request with a JSON encoded body.
When you use Postman, you must have configured it to use a multipart or www-url-encoded body.
PHP will automatically decode request bodies using those formats.
Postman does something else then an AJAX post. One will post your classic html form with application/x-www-form-urlencoded, the other is posting straight json with a different contenttype.
bottomline: The php $_POST variable does not containt everyting you send with a POST http request!
also see here, this is an excellent explanation: PHP "php://input" vs $_POST

angular-php: form data is empty in php

I am using angular as frontend and php as backend here is the code of angular.
$scope.processForm = function($scope.formData) {
console.log($scope.formData);
$http({
method : 'POST',
url : 'process.php',
data : {'data': $scope.formData,'uid':uid}, // no need to use $.param, even never see it in angular
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
here is the process.php
$postContent= file_get_contents("php://input");
$req= json_decode($postContent);
$formData= $req->formData;
$uid= $req->uid;
problem is $formData is empty in php. however $uid is showing value.
in form i have two entry email and password but i don't know how can i use that in php because formdata is empty.
I checked in firebug and found data is posting.
{"formData":{"password":"ff","cpassword":"errgreg"},"uid":"75"}:""
But nothing is coming response tab of firebug.
Assuming you call your function with something like ng-submit="processForm(formData)" then this is all you actually need
$scope.processForm = function(formData) {
$http.post('process.php', {
formData: formData, // note the key is "formData", not "data"
uid: uid // no idea where uid comes from
});
};
Where you have
$scope.processForm = function($scope.formData) {
isn't even valid JavaScript. You cannot use object dot notation in function argument names. That should have been throwing an error in your console.
You also appeared to be incorrectly setting your request content-type. You are sending JSON, not application/x-www-form-urlencoded formatted data. Angular's default POST content-type (application/json) is sufficient.
Try like this..
$json='{"formData":{"password":"ff","cpassword":"errgreg"},"uid":"75"}';
$req= json_decode($json);
$formData= $req->formData;
$uid= $req->uid;
$password = $req->formData->password;
$cpassword = $req->formData->cpassword;
OR convert into array using json_decode() with second argument as true.
$json='{"formData":{"password":"ff","cpassword":"errgreg"},"uid":"75"}';
$req= json_decode($json,true);//converts into array format
$formData= $req['formData'];
//print_r($formData);
echo $formData['password'];

I would like to normalize my json data on server side for XSS prevention. Am i doing it the right way?

I am implementing the XSS prevention cheat rules in my app and I currently working on escaping/securing Json data and wondering if I am doing it right?
According to Rule 3.1 in the XSS prevention cheat sheet "An alternative to escaping and unescaping JSON directly in JavaScript, is to normalize JSON server-side by converting '<' to '\u003c' before delivering it to the browser."
So I have created a function in php called normalizeJson which takes in an associative array as a parameter and converts all < characters to \u003c, returning the data in json format.
I am wondering if this is the best way to do this?
I'm unsure as to whether it is ok to json_encode twice here however it didn't work when I had return $new_json (without json_encoding it again.)
function normalizeJson($data){
$json = json_encode($data);
$new_json = str_replace("<","\u003c",$data);
return json_encode($new_json);
}
Also it states in the same rule, "read the data with JSON.parse" however when I use the contentType: "application/json;charset=utf-8" in my ajax request and try parse the response with JSON.parse(data) it doesn't work.
It works perfect without JSON.parse(). I'm guessing this is because it is expecting json as a response anyway and so doesn't need to parse it with JSON.parse() but I would like clarification on this if anyone knows.
Client side Ajax request:
var token = localStorage.getItem("usertoken");
var params = {'usertoken': token, 'engage_post_text' : engage_post_text, 'post_type' : post_type};
$.ajax({
//do an ajax request passing along the user json web token for validation on server side and also the text that was submitted.
url: app_root_url + 'submit_post.php',
data: JSON.stringify(params),
type: "POST",
dataType: "json",
contentType: "application/json;charset=utf-8",
success: function(data){
var result = data;//JSON.parse(data);
var successful_insert = result.successful_insert;
if(successful_insert){
//do stuff with json data
}else{
//error
}
}
});
My php code where the ajax request is sent, and I use the normalizeJson function before returing the json back to the client side.
//need to get the data this way because we have contentType application/json set, so $_POST will no longer be populated
$rawPostData = file_get_contents('php://input');
$json = json_decode($rawPostData);
if(isset($json->usertoken)){
$token = JWT::decode($json->usertoken, 'secret_server_key'); //this will return an error if token has been tampered with
$data = array();
if($token->userID){
//token is valid and therefore user is valid so we go ahead submit the form.
$data['token_is_valid'] = true;
if(isset($json->engage_post_text)){
$postText = $json->engage_post_text;
$postType = filter_var($json->post_type, FILTER_SANITIZE_STRING);
$postTime = time();
$user_id = $token->userID;
$result = insertEngagePost($postTime, $user_id, $postText, $postType, $pdoConnection);
if($result['successful_insert'] == true){
$data['successful_insert'] = true;
$data['post_id'] = $result['post_id'];
$data['userDetails'] = getProfile($user_id, $pdoConnection);
}else{
$data['successful_insert'] = false;
}
//send back json to client side ajax request
echo normalizeJson($data);
}
}else{
//token is set but is not valid
$data['token_is_valid'] = false;
echo normalizeJson($data);
}
}else{
//token is not set.
}

Ajax + PHP: null instead of an array

Ajax call is made in the background
var signupValidate = function(elementID){
var value = $('#' + elementID).val();
if (value !== ''){
$('#'+elementID+'-status').css("background-image", "url(img/signup/spinner.gif)");
var data = {elementID: value};
var json = JSON.stringify(data);
$.ajax({
url: 'php/validator_signup.php',
dataType: 'json',
type: 'post',
data: json,
success: function(data){
var parsedResponse = JSON.parse(data);
console.log(parsedResponse);
/*
if(data.response === 1){
$('#'+elementID+'-status').css("background-image", "url(img/signup/no.png)");
}else if(data.response === 0){
$('#'+elementID+'-status').css("background-image", "url(img/signup/yes.png)"); }
*/
}
});
}
}
validator_signup.php received the call. So far in test mode PHP will receive the string, parse it and encode again to return to JS:
$post = $_POST['data'];
$data = json_decode($post, true); //decode as associative array
$details = $data[0];
echo json_encode($details);
JS then needs to print this in console.
I get this:
null
instead of the value which I expect back.
Result is same whether I parse returned data or not.
If I understand it correctly, the problem is on PHP side?
There does not appear to be any value in converting to json when your data is so simple, you can just use a regular js object that jquery will convert to form data.
Also, as both the key and value you send are unknown, i would suggest sending the data in a different structure so its easy to retrieve:
var signupValidate = function(elementID){
var value = $('#' + elementID).val();
if (value !== ''){
$('#'+elementID+'-status').css("background-image", "url(img/signup/spinner.gif)");
$.ajax({
url: 'php/validator_signup.php',
type: 'post',
// ▼key ▼value ▼key ▼value
data: { id: elementID, val: value},
success: function(response){
console.log(response.message);
}
});
}
}
In php you can access the data via $_POST, and as you know the keys, its simple:
<?php
$id = $_POST['id'];
$val = $_POST['val'];
//set correct header, jquery will parse the json for you
header('Content-Type: application/json');
echo json_encode([
'message'=>'Request received with the id of: ' . $id . 'and the value of: ' . $val,
]);
die();
Change:
data: json,
To:
data: { data: json},
This is because you aren't giving the sent data a POST parameter to then be used server side to retrieve it.
Then, you can simply fetch the code server-side like this:
$data = json_decode($_POST['data']);
Hope this helps!
Here, since you are checking whether data is being post, if you see in Network, no data is being posted. To fix it, change this part:
var data = {elementID: value};
To this:
var data = {data: {elementID: value}};
Consider removing conversion of Data
PHP automatically handles the $_POST as an array! So you don't need to use the reconversion. Please eliminate this part:
var json = JSON.stringify(data); // Remove this.
And in the server side:
$data = json_decode($post, true); // Remove this
$data = $_POST['data']; // Change this
Update
OP said data[elementID]:gh is sent to the PHP file.
If this is the case, then if the data needs to be "gh" in JSON, then:
$res = $_POST["elementID"];
die(json_encode(array("response" => $res)));
This will send:
{
"response": "gh"
}
And in the client side, you don't need anything other than this:
$.post('php/validator_signup.php', function (data) {
var parsedResponse = JSON.parse(data);
console.log(data);
});
JSON data is sent to the server as a raw http input it is not associated with query name like $_POST['data'] or anything like that which means you must access the input string not a data post value to do so you need to use
$rawInput = json_decode(file_get_contents('php://input'), true);
$elementValue = $rawInput['elementId'];
thats it
$_POST = json_decode(file_get_contents('php://input'), true);
$data = $_POST['data'];

Categories