My JSON isn't being decoded by PHP - php

My PHP script is having a problem decoding the JSON that I'm sending to it via AJAX.
The jQuery:
$.ajax({
url : 'admin/modifyPermissions',
type : 'post',
data : {
'JSON' : JSON
},
success : function(msg){
if(msg == '1') {
alert('Permissions saved successfully');
} else {
alert(msg);
}
}
});
The PHP script:
public function modifyPermissions(){
if(isset($_POST['JSON']) && !empty($_POST['JSON'])) {
$json = json_decode($_POST['JSON'],true);
if($json !== NULL && $json !== FALSE) {
} elseif($json === NULL){
die('The string passed is not a valid JSON object and cannot be decoded.' . "\n" . $_POST['JSON']);
} else {
die('There was an error with the JSON string');
}
} else {
die('No JSON string was sent!');
}
}
The JSON that gets passed looks well formed to me:
{"martin":{3,5},"user2":{3,4,5}}
And PHP is returning null. I have PHP 5.2.7 installed on my server, so I can't use json_last_error()

{"martin":{3,5},"user2":{3,4,5}}
Not valid JSON. Valid JSON may look like this:
{"martin":[3,5],"user2":[3,4,5]}

You're not sending valid JSON, thus the error. Look at the comment #Matt added.
So that you won't reproduce the same error, before sending it over to PHP, don't try to make your own JSON string, use what JS offers you. Example:
var obj = { key: val, okey: oval }
objJSON = JSON.stringify(obj)
// objJSON is ALWAYS going to be valid json

Your JSON is invalid.
The {} notation denotes key/value pairs, where as you're using it as an array.
Your JSON should be,
{"martin":[3,5],"user2":[3,4,5]}

Related

Sending JSON to PHP via jQuery AJAX [duplicate]

This question already has answers here:
Sending JSON to PHP using ajax
(8 answers)
Closed 5 years ago.
I have looked at a bunch of questions/answers on here and none of them seem to solve my problem. I am integrating a payment system that returns a JSON string via a JS library that I then need to parse on the server to compare the hash values to ensure that it is valid. So I get their response and attempt to pass it via jQuery AJAX to a PHP file on the server. The response I get from the payment system is valid JSON. If I pass it directly the result I get on the server seems to be URL encoded. If I JSON.stringify() it, it adds a bunch of extra quotes which results in invalid JSON.
function isValidJSON($str) {
json_decode($str);
return json_last_error() == JSON_ERROR_NONE;
}
$json_params = file_get_contents("php://input");
error_log($json_params);
//error_log($_POST['jsresp']);
//$respObj = json_decode(stripslashes($_POST['jsresp']));
//error_log($json_params);
if (strlen($json_params) > 0 && isValidJSON($json_params)) {
$respObj = json_decode($json_params);
} else {
error_log('bad json '.$json_params);
}
$result = 0;
$resp = json_encode($respObj->Response);
$hash = $respObj->Hash;
error_log($hash);
$calcHash = base64_encode(hash_hmac('sha512', $resp, $app->getSageClientSecret(), true));
error_log($calcHash);
if($hash === $calcHash) {
$result = 1;
}
$app->updateCartResponse($_COOKIE['qid'], $result);
And here is the jQuery AJAX call to send the data:
$(document).on('click', 'button#sps-close.sps.btn.btn-primary', function(){
var resp = $("#resp_holder").val();
$.ajax({
url: "<?=$env?>sources/processors/process_hash.php",
data: { jsresp : resp },
type: "post",
//dataType: "json",
success: function( data ) {
// nothing to do here.
}
});
var url = $("#redirect_url").val();
if(url != "") {
location.href = $("#redirect_url").val();
}
});
When I do it this way, the JSON that gets to the server looks like this:
jsresp%5Bresponse%5D=%7B%22requestId%22%3A%22443594%22%2C%22gatewayResponse%22%3A%7B%22status%22%3A%22Approved%22%2C%22reference%22%3A%22EBGHNHChw0%22%2C%22message%22%3A%22APPROVED+658658%22%2C%22code%22%3A%22658658%22%2C%22cvvResult%22%3A%22P%22%2C%22avsResult%22%3A%22+%22%2C%22riskCode%22%3A%2200%22%2C%22networkId%22%3A%2210%22%2C%22isPurchaseCard%22%3Afalse%2C%22orderNumber%22%3A%22443594%22%2C%22transactionId%22%3A%22NDViMWYzNmEwNWNiOGQxZjIwOTAwNzU4MmVjYzJhMWQ%22%2C%22timestamp%22%3A%222017-11-16T23%3A17%3A12.6584893-05%3A00%22%7D%7D&jsresp%5Bhash%5D=bgd1e0Cxhj5s1FQaUFFYk7BMnSIl4Ez1jPMopZFp%2B4MyN9chFZZoo%2F3IuZPX7bbQ%2BRyaReKN1CNJXxRmjnLMRQ%3D%3D
I don't understand what I'm doing wrong or how to get it there properly.
Based on your sample, this is what you get on the server
jsresp[response]={"requestId":"443594","gatewayResponse":{"status":"Approved","reference":"EBGHNHChw0","message":"APPROVED 658658","code":"658658","cvvResult":"P","avsResult":" ","riskCode":"00","networkId":"10","isPurchaseCard":false,"orderNumber":"443594","transactionId":"NDViMWYzNmEwNWNiOGQxZjIwOTAwNzU4MmVjYzJhMWQ","timestamp":"2017-11-16T23:17:12.6584893-05:00"}}&jsresp[hash]=bgd1e0Cxhj5s1FQaUFFYk7BMnSIl4Ez1jPMopZFp+4MyN9chFZZoo/3IuZPX7bbQ+RyaReKN1CNJXxRmjnLMRQ==
So your $_REQUEST['jsresp'] is an array
you need to json_decode the 'response' index of the array :
$respObj = json_decode($_REQUEST['jsresp']['response']);
$hash = $_REQUEST['jsresp']['hash'];
And then you can go on...
First i will advice you to look at the value in your #resp_holder, if the value there is correct as you want it, then you can post it using anyhow you want it, json is a string, and as long as that string conforms to json standard, and they are no special characters in the it like &, then you can decode it in your php.
You can use html or json dataType to post it.

json_encode(string) giving backslashes in response

I am creating an array of objects in js and sending it to one of my controllers after stringify'ing the array.
var arr = new Array();
for(i=0;i<noOfDeals;i++){
var deals = {'percentageMin':document.getElementById("pmin"+i).value,
'percentageMax':document.getElementById("pmax"+i).value,
'modelApplicable': document.getElementById("model"+i).value,
'maxCashback' : document.getElementById("maxcash"+i).value,
'dealId' : document.getElementById("deal"+i).value
};
arr.push(deals);
}
alert(JSON.stringify(arr));
$.ajax({method:'get',url:'abc?data='+JSON.stringify(arr),success:function(response) {
//response = JSON.parse(response);
response = JSON.parse(response);
alert(response.body);
response = JSON.parse(response.body);
if(response.status != undefined && response.status == 'SUCCESS') {
alert('Merchant details updated successfully. Refresh the page to see the changes.');
}
else {
alert('Could not update merchant details, Some Error Occurred');
}
}});
In my controller i am encoding the data and then sending to hit the API :
public function updateselectedmerchants(){
if (isset($_GET['data'])) {
$str_data = $_GET['data'];
print_r(json_encode(array('deals' => $str_data)));
die;
}
}
The Output :
{"deals":"[{\"percentageMin\":\"1.00\",\"perentageMax\":\"0.00\",\"modelApplicable\":\"3\",\"maxCashback\":\"30.00\",\"dealId\":\"7\"}"}
The desired output :
{"deals":[{\"percentageMin\":\"1.00\",\"perentageMax\":\"0.00\",\"modelApplicable\":\"3\",\"maxCashback\":\"30.00\",\"dealId\":\"7\"}]}
There are three things which are unwanted in the output which is coming :
1) The double quotes before the first square brackets should not be there.
2) The ending square bracket is not present
3) "/" appearing
Please help me with this.
You should do
$str_data = json_decode($_GET['data'], true);
print_r(json_encode(array('deals' => $str_data)));
Otherwise $str_data remains a string, and will be JSON encoded as such, while it looks like you want it to be a PHP array structure, and then encode all of that into valid JSON again.
See this PHP 'fiddle'
You probably generate " or ' somewhere you dont want to.
Not sure if it work 100%, but try:
public function updateselectedmerchants(){
if (isset($_GET['data'])) {
$str_data = json_decode($_GET['data']);
print_r(json_encode(array('deals' => $str_data)));
die;
}
}
You should try PHP approach:
http://php.net/manual/en/function.urlencode.php
http://php.net/manual/en/function.urldecode.php
Just decode array and encode it on the other side.

jQuery Ajax sending empty data

I'm doing a code that send a data to a php file and send it back again and print it as a response however when i send the data it is sent as an empty data i did not know what is the problem this is the code that i tried:
var resource = $('#resource').val().replace(/[\n\r](?!\w)/gi, "").split("\n");
function doRequest(index) {
// alert(resource[0]); The data here is ok and it is not empty whenever the data is sent the response is empty !
$.ajax({
url:'curl_check.php?email='+resource[0],
async:true,
success: function(data){
alert(data);
if (resource.length != 1) {
removeResourceLine();
doRequest(index+1);
}
}
});
}
doRequest(0);
since you're not sending the data using the data property of the ajax call object like so:
$.ajax({
...
data : { email : resource[0] }
...
});
you are sending it as part of the URL, so it should be picked up as a GET variable. in php, this looks like:
$email = isset($_GET['email']) ? $_GET['email'] : false;
that said, i'd suggest using the ajax data property and specifying the type property and setting it to GET or POST. you could also use $.ajaxSetup
Ok I am not sure what is wrong with what you are doing but I am going to give you code I use to send data to php and get a response. I am going to do it with json because it is awesome. I hope it helps:
var resource = $('#resource').val().replace(/[\n\r](?!\w)/gi,"").split("\n");
function doRequest(index) {
$.post("curl_check.php", {
email: resource[0]
}, function(data, result, xhr){
if(result == 'success') {
console.log(data.success);
} else {
console.log('post failed');
}
}, "json");
}
The php code:
$json = array();
$email = $_POST['email']; //Please escape any input you receive
//Do what you have to do
$json['success'] = 'YAY IT WORKED';
die(json_encode($json));

Ajax check if result is json or not [duplicate]

My server side code returns a value which is a JSON object on success and a string 'false' on failure. Now how can I check whether the returned value is a JSON object?
The chosen solution doesn't actually work for me because I get a
"Unexpected Token <"
error in Chrome. This is because the error is thrown as soon as the parse comes across and unknown character. However, there is a way around this if you are returning only string values through ajax (which can be fairly useful if you are using PHP or ASPX to process ajax requests and might or might not return JSON depending on conditions)
The solution is quite simple, you can do the following to check if it was a valid JSON return
var IS_JSON = true;
try
{
var json = $.parseJSON(msg);
}
catch(err)
{
IS_JSON = false;
}
As I have said before, this is the solution for if you are either returning string type stuff from your AJAX request or if you are returning mixed type.
jQuery.parseJSON() should return an object of type "object", if the string was JSON, so you only have to check the type with typeof
var response=jQuery.parseJSON('response from server');
if(typeof response =='object')
{
// It is JSON
}
else
{
if(response ===false)
{
// the response was a string "false", parseJSON will convert it to boolean false
}
else
{
// the response was something else
}
}
Solution 3 (fastest way)
/**
* #param Object
* #returns boolean
*/
function isJSON (something) {
if (typeof something != 'string')
something = JSON.stringify(something);
try {
JSON.parse(something);
return true;
} catch (e) {
return false;
}
}
You can use it:
var myJson = [{"user":"chofoteddy"}, {"user":"bart"}];
isJSON(myJson); // true
The best way to validate that an object is of type JSON or array is as follows:
var a = [],
o = {};
Solution 1
toString.call(o) === '[object Object]'; // true
toString.call(a) === '[object Array]'; // true
Solution 2
a.constructor.name === 'Array'; // true
o.constructor.name === 'Object'; // true
But, strictly speaking, an array is part of a JSON syntax. Therefore, the following two examples are part of a JSON response:
console.log(response); // {"message": "success"}
console.log(response); // {"user": "bart", "id":3}
And:
console.log(response); // [{"user":"chofoteddy"}, {"user":"bart"}]
console.log(response); // ["chofoteddy", "bart"]
AJAX / JQuery (recommended)
If you use JQuery to bring information via AJAX. I recommend you put in the "dataType" attribute the "json" value, that way if you get a JSON or not, JQuery validate it for you and make it known through their functions "success" and "error". Example:
$.ajax({
url: 'http://www.something.com',
data: $('#formId').serialize(),
method: 'POST',
dataType: 'json',
// "sucess" will be executed only if the response status is 200 and get a JSON
success: function (json) {},
// "error" will run but receive state 200, but if you miss the JSON syntax
error: function (xhr) {}
});
If you have jQuery, use isPlainObject.
if ($.isPlainObject(my_var)) {}
var checkJSON = function(m) {
if (typeof m == 'object') {
try{ m = JSON.stringify(m); }
catch(err) { return false; } }
if (typeof m == 'string') {
try{ m = JSON.parse(m); }
catch (err) { return false; } }
if (typeof m != 'object') { return false; }
return true;
};
checkJSON(JSON.parse('{}')); //true
checkJSON(JSON.parse('{"a":0}')); //true
checkJSON('{}'); //true
checkJSON('{"a":0}'); //true
checkJSON('x'); //false
checkJSON(''); //false
checkJSON(); //false
Since it's just false and json object, why don't you check whether it's false, otherwise it must be json.
if(ret == false || ret == "false") {
// json
}
I know this thread has been answered already, but coming here didn't really solve my problems, I found this function somewhere else.
maybe someone coming here will find it to be of some use to them;
function getClass(obj) {
if (typeof obj === "undefined")
return "undefined";
if (obj === null)
return "null";
return Object.prototype.toString.call(obj)
.match(/^\[object\s(.*)\]$/)[1];
}
var data = 'json string ?';
var jdata = null;
try
{
jdata = $.parseJSON(data);
}catch(e)
{}
if(jdata)
{
//use jdata
}else
{
//use data
}
If you want to test explicitly for valid JSON (as opposed to the absence of the returned value false), then you can use a parsing approach as described here.
I don't really like the accepted answer. First and foremost it requires jQuery, which is not always available or required. Secondly, it does a full stringification of the object which to me is overkill. Here's a simple function that thoroughly detects whether a value is JSON-like, using nothing more than a few parts of the lodash library for genericity.
import * as isNull from 'lodash/isNull'
import * as isPlainObject from 'lodash/isPlainObject'
import * as isNumber from 'lodash/isNumber'
import * as isBoolean from 'lodash/isBoolean'
import * as isString from 'lodash/isString'
import * as isArray from 'lodash/isArray'
function isJSON(val) {
if (isNull(val)
|| isBoolean(val)
|| isString(val))
return true;
if (isNumber(val))
return !isNaN(val) && isFinite(val)
if (isArray(val))
return Array.prototype.every.call(val, isJSON)
if (isPlainObject(val)) {
for (const key of Object.keys(val)) {
if (!isJSON(val[key]))
return false
}
return true
}
return false
}
I've even taken the time to put it up in npm as a package: https://npmjs.com/package/is-json-object. Use it together with something like Webpack to get it in the browser.
Hope this helps someone!
I am using this to validate JSON Object
function isJsonObject(obj) {
try {
JSON.parse(JSON.stringify(obj));
} catch (e) {
return false;
}
return true;
}
I am using this to validate JSON String
function isJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
i tried all of the suggested answers, nothing worked for me, so i had to use
jQuery.isEmptyObject()
hoe that helps someone else out with this issue
You should return json always, but change its status, or in following example the ResponseCode property:
if(callbackResults.ResponseCode!="200"){
/* Some error, you can add a message too */
} else {
/* All fine, proceed with code */
};

Ampersand in JSON/PHP in POST

I'm having a text field which is send via JSON and jQuery (wrapped with .toJSON function) to my server via AJAX and POST request. On PHP side I'm doing json_decode .
Everything works but if I put ampersand (&) inside it splits up the POST parameter so its incomplete on PHP side (at least what var_dump($_POST) is writing out).
Shouldn't the toJSON and json_decode do all the job (escaping)? I tried encodeURIComponent, & to &, & to \u0026 and it's not working.
What I'm doing wrong?
AJAX call
function execute() {
this.setupUrl();
return $.ajax({
type: this.requestMethod,
data: this.getDataParams(),
url: this.url
});
}
function getDataParams() {
if(this.data != undefined) {
if(this.requestMethod == 'POST' || this.requestMethod == 'PUT') {
return "data=" + $.toJSON(this.data);
} else if(this.requestMethod == 'GET') {
return this.data;
}
} else {
return null;
}
}
The answer is simple: Use an object for data instead of a string.
E.g. change your function like this:
return {data: $.toJSON(this.data)};
This will work in any case, no matter if you are using POST or GET.
& should be encoded as %26. Find something that does so.
you don't need the "data" thing, as you already have it in execute()
if(this.requestMethod == 'POST' || this.requestMethod == 'PUT') {
return $.toJSON(this.data);
}
This is wierd. PHP and JS work together many yaers. Couldn't expect that php cant decode what js coded. So i'll need a special function to handle this.
function damn_ampersand(str){
return str.replace('&', '%26');
}
obj = {"ololo": damn_ampersand("atata & foobar")}
json = JSON.stringify(obj);

Categories