Javascript Object to a PHP Object
I was searching for the tutorial how to pass associative array from JavaScript to PHP object and found this video. I think it is a little bit old it was added in 2010. I tried it and had error. I ask you to help me to correct it or help me to to get php object from js object.
index.php
<script>
let ar = new Array();
ar["name"] = "name1";
ar["name1"] = "name2";
console.log(ar);
function convertOb(object){
var json = "{";
for (property in object) {
var value = object[property];
if (typeof(value) == "string") {
json += '"' + property + '":"' + value +'",';
} else{
if (!value[0]) {
json += '"' + property + '":"' + convertOb(value) + ',';
} else{
json+= '"'+ property +'":[';
for (prop in value) json+= '"' + value[prop] + '",';
json = json.substr(0,json.length-1) + "],";
}
}
} return json.substr(0,json.length-1) + "}";
}
let json = convertOb(ar);
$.post("main.php", {json:json}, function(data){
console.log(data);
});
</script>
main.php
<?php
function jsonstring2obj($str){
return json_decode(stripslashes($str));
}
$ar = jsonstring2obj($_POST['json']); //error1
echo $ar->name; //error2
?>
My errors:
Undefined index: json //error1
Trying to get property 'name' of non-object //error2
Related
I have complex json data. It can be in either formats as below :
1. {"Physics":{"5b87ceb691":"Motion","5b87ce3e":"Mass"}} //where value itself is a json
2. {"a60a8001805":"Finish chapter 1","a60a8002ab0":"Finish assignments"} //simple key value pair
I want to create checkboxes for all values (Motion, Mass, Finish chapter 1, Finish assignments for above examples) and keys should come like text in between those checkboxes (Physics for above example) (Key should come like text only if it's value is a json object, since Physics's value is a json, Physics should show like a text and in example 2, since there are no such keys whose value is a json object, no key will show like a text).
I've implemented this in javascript in the following way :
var str = "";
if(Object.keys(data).length !== 0) {
var i = 1;
for (var key in data) {
if (data.hasOwnProperty(key)) {
var val = data[key];
if(typeof val == 'object') {
str += '<div class = "data_text hidden">' + key + '</div>';
for (var subKey in val) {
if (val.hasOwnProperty(subKey)) {
var subValue = val[subKey];
str += '<div class="db-checkbox data_options hidden"><input type="checkbox" name="abc" id="' + i + '"><label for="' + i + '">' + subValue + '</label></div>'
i += 1;
}
}
} else {
str += '<div class="db-checkbox data_options hidden"><input type="checkbox" name="abc" id="' + i + '"><label for="' + i + '">' + val + '</label></div>'
i += 1;
}
}
}
Now, I want to do the same in php. I searched to find out the way to access json data in php, but all of those works only when keys are known. (For example, data->a60a8002ab0) But I want to do this generically. Don't want to hardcode anything. How can I do this? Thank you.
Try json_decode in associative mode by passing in the second param true so that it returns an associative array that you can loop through, similar to your javascript code.
//try each of the following by comment/uncomment
//$myjson = '{"Physics":{"5b87ceb691":"Motion","5b87ce3e":"Mass"}}';
//$myjson = '{"a60a8001805":"Finish chapter 1","a60a8002ab0":"Finish assignments"}';
$myjson = '{"a60a8001805":"Finish chapter 1","a60a8002ab0":"Finish assignments","Physics":{"5b87ceb691":"Motion","5b87ce3e":"Mass"}}';
$json_md_ary = json_decode($myjson,true);
$i=1;
foreach($json_md_ary as $key=>$val){
if (is_array($val)){
echo $key, "<br>";
foreach($val as $k=>$v){
echo $k, ' => ' ,$v,'<input type="checkbox" name="abc" id="'.$i.'">',"<br>";
$i++;
}
}else{
echo $key, ' => ' ,$val,'<input type="checkbox" name="abc" id="'.$i.'">',"<br>";
$i++;
}
}
$jsondata = '{"Physics":{"5b87ceb691":"Motion","5b87ce3e":"Mass"}}';
$data = json_decode($jsondata);
foreach($data as $key => $val){
print_r($val);
}
Below are a couple of queries that ultimately build an array.
if(isset($_POST['getarray'])){
try{
$ret = array();
$stmt = $db->prepare('SELECT groupdate, groupid
FROM participationtemp
WHERE memberid = :memberid
AND groupid = :groupid
ORDER BY groupdate, groupid DESC');
$stmt->bindValue(':groupid', $_POST['groupid'], PDO::PARAM_INT);
$stmt->bindValue(':memberid', $_SESSION['memberid'], PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll();
foreach($result as $row){
$attenddate = $row[0];
$stmt = $db->prepare('SELECT h.clientid, attend, attend_date
FROM history AS h
INNER JOIN suspended AS s on s.clientid = h.clientid
WHERE h.memberid = :memberid
AND h.groupid = :groupid
AND attend_date = :attenddate
AND suspend = "N"');
$stmt->bindValue(':memberid', $_SESSION["memberid"], PDO::PARAM_INT);
$stmt->bindValue(':groupid', $_POST['groupid'], PDO::PARAM_INT);
$stmt->bindValue(':attenddate', $attenddate, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll();
foreach($result as $row ) {
array_push($ret, ['id' => $row[0], 'gdate' => $row[2]]);
}
}
echo json_encode($ret);
exit();
} catch (PDOException $ex){
mail_error($ex);
}
}
After returning to JQuery, alert(re); shows I successfully created the array.
success:function(re){
alert(re);
But I'm having trouble accessing the array data. Without success, this is what i've tried:
data = $.parseJSON(re);
$.each(data, function(i, val) {
alert(i + "=" + val);
});
and this:
data = $.parseJSON(re);
$.each(data, function(i, val) {
if(i == "id"){
alert(i + "=" + val);
}
if(i == "gdate"){
alert(i + "=" + val);
}
});
I've also tried dot notation.
$.each(re.id, function(i, val) {
alert(i + "=" + val);
}
});
$.each(re.gdate, function(i, val) {
alert(i + "=" + val);
});
I've never used JSON before and don't understand why I can't retrieve the array data. Any help will be appreciated. Thanks.
The following code checks whether re is a string, or an object. The latter is possible if jQuery.ajax() method is used with "json" dataType. Also, jQuery is capable of parsing JSON automatically, if the response MIME type is application/json (the Content-Type HTTP header), particularly. So it is a good idea to check if re has been parsed by jQuery.
var d = typeof re === 'string' ? JSON.parse(re) : re;
var i;
for (i = 0; i < d.length; i++) {
console.log("id = ", d[i].id,
"gdate = ", d[i].gdate);
}
I'd recommend returning the appropriate content type from PHP:
header ('Content-Type: application/json');
echo json_encode($ret);
exit();
$.each(re, function(i, val) {
alert(val.id + "=" + val.gdate);
});
Try this code :)
// Json in string format
var jsonString = '[{"id":"1", "gdate":"2016-10-13"},{"id":"2", "gdate":"2016-10-13"},{"id":"3", "gdate":"2016-10-13"},{"id":"4", "gdate":"2016-10-13"},{"id":"5", "gdate":"2016-10-13"},{"id":"6", "gdate":"2016-10-13"}]';
// Convert string to json object
var json = JSON.parse(jsonString);
// Iterate over json object
jQuery.each(json, function(index, value) {
console.log(index, value);
});
// Simple access to attribute in json object
console.log('json[1][\'id\'] = ', json[1]['id']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am trying to iterate a JSON structure in a recursive way. I checked other forums / stackoverflow questions but I seem to have a strange problem.
So what comes from the REST service is :
{/Envelope=
{/Envelope/Header = {},
/Envelope/Body =
{/Envelope/Body/ns:GetAddressForPostCodeResponse=
{/Envelope/Body/ns:GetAddressForPostCodeResponse/ns:maximumAddressMatches = ? ,
/Envelope/Body/ns:GetAddressForPostCodeResponse/ns:postalAddress =
{/Envelope/Body/ns:GetAddressForPostCodeResponse/ns:postalAddress/ns:apartment = ? ,
...
Basically I send back a Map from SpringMVC with a String key and having an other Map as value.
The (angular) code:
$scope.getHtml = function(node, isAdd) {
if (isAdd) {
var html = "<ul id='tree1'>";
} else {
var html = "<ul>";
}
//angular.forEach(node, function(value, key) {
for (var key in node) {
if (node.hasOwnProperty(key)) {
var value = node[key];
console.log(key + " : " + value);
console.log(node.hasOwnProperty(key));
if (key != "$promise" && key != "$resolved") {
html += "<li><input type='checkbox' id='" + key + "'><label>" + key + "</label>";
html += $scope.getHtml(value, false);
}
}
//});
}
html += "</ul>";
delete node;
return html;
};
As you can see there is a recursive call.
And what I can see in the console:
true serviceDiscovery.controller.js:39
"0 : ?" serviceDiscovery.controller.js:38
true serviceDiscovery.controller.js:39
"0 : ?" serviceDiscovery.controller.js:38
... (the same two rows some thousands times)
"0 : ?" serviceDiscovery.controller.js:38
true serviceDiscovery.controller.js:39
"Error: too much recursion
$scope.getHtml/<#http://localhost:8080/management-app-1.0.0-SNAPSHOT/resources/js/serviceDiscovery.controller.js:37:21
r#http://localhost:8080/management-app-1.0.0-SNAPSHOT/resources/js/angularjs/angular.min.js:7:288
So there is an infinite loop but how...? I tried the angular.forEach too.
Any idea?
------------- UPDATE -------------
Hmm, my mistake, sorry. I only need the recursive call if the value is a map (object) and not a String.
This is my response from AJAX call
{"screen":[{"screen_name":"SCR1","screen_id":"1"},{"screen_name":"SCR2","screen_id":"2"},{"screen_name":"SCR3","screen_id":"3"},{"screen_name":"SCR4","screen_id":"4"},{"screen_name":"SCR5","screen_id":"5"},{"screen_name":"BIGSCR","screen_id":"6"}]}
success: function(response) {
var jsondata = JSON.stringify(response);
console.log(jsondata);
var html = '';
for (var i = 0; i < jsondata.screen.length; i++) {
var screenName = jsondata.screen[i].screen_name;
var screenId = jsondata.screen[i].screen_id;
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
}
But I keep on getting
Uncaught TypeError: Cannot read property 'length' of undefined at for loop
Try this: It Works. As smooth as silk: (See comment for explanation)
<select id="SCname"></select>
<script>
$.ajax({
dataType: 'json',
//This JSON datatype returns a json encoded response
url:"api/test.php",
//This is the URL From where you fetch the JSON Data
success: function(response){
//Since the response array object has a single array element "screen", we make it myArray
myArray = response["screen"];
console.log(myArray);
//We get six Objects in myArray.
//Thsese are Arrays of your six screens . Now Using Loops
var html = '';
for (var i = 0; i < myArray.length; i++) {
// Each element is inside DOuble Array like: myArray[0]["screen_name"]
var screenName = myArray[i]["screen_name"];
var screenId = myArray[i]["screen_id"];
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
//Check your console ouput
console.log(html);
}
});
</script>
JSON.stringify(object) returns a string. You want a JSON.parse(string) – which returns an object. Alternatively, if your response is already an object, then you don't have to parse it at all:
success: function(jsonData) {
var html = '';
for (var i = 0; i < jsonData.screen.length; i++) {
var screenName = jsonData.screen[i].screen_name;
var screenId = jsonData.screen[i].screen_id;
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
You don't want to stringifybut to parse. Correct it must be:
var jsondata = JSON.parse(response);
But keep in mind that jQuery possibly is already parsing the JSON for you.
I'm making an ajax call to retrieve some JSON objects. I get them right. but the problem is when I want to create a select element from returned JSON, it doesn't create one or seemed to be.
My JavaScript so far:
jQuery("#make").change(function () {
var value = $(this).val();
jQuery.getJSON("<?php echo site_url('ajax/get/models'); ?>", {
makeId: value
},
function (data) {
if (data != "false") {
var modelsSelect = jQuery.createElement('select');
var modelsOptions = "";
var id;
var model
jQuery.each(data, function () {
jQuery.each(this, function (key, value) {
if (key == "id") {
id = value;
} else {
model = value;
}
});
modelsOptions += "<option value=" + id + ">" + model + "</option>"
});
modelsSelect.innerHTML = modelsOptions;
jQuery("#model").html = modelsSelect;
} else {
alert("false");
}
});
});
my returned JSON Format:
Object { id="28", model="test model"}
There could be n number of JSON objects in returned response from ajax call.
There is no createElement method in jQuery
jQuery.createElement should be document.createElement
Also no need to loop over the objects' properties, you can access them by the key directly
jQuery.each(data, function (index, item) {
modelsOptions += "<option value=" + item.id + ">" + item.model + "</option>"
});
Change this
jQuery("#model").html = modelsSelect;
to
jQuery("#model").html(modelsSelect);
Reference
.html()