I'm trying to encode a json response using php, and having some trouble formatting it for use with ajax.
I'm basically trying to return an array of Rental objects, which each will include data for book, student, and teacher. Currently I'm using php to build objects like this...
while ($row = $result->fetch_array(MYSQLI_BOTH)) {
$obj = array();
// Build a book out of the results array, then push to the current object
$book = new Book();
$book->id = $row['book_id'];
$book->title = $row['title'];
$book->author = $row['author'];
$book->ar_quiz = $row['ar_quiz'];
$book->ar_quiz_pts = $row['ar_quiz_pts'];
$book->book_level = $row['book_level'];
$book->type = $row['type'];
$book->teacher_id = $row['teacher_id'];
array_push($obj, array('book' => $book));
// Build a student out of the results array, then push it to the current objects
$student = new Student();
$student->id = $row['student_id'];
$student->username = $row['student_username'];
$student->nicename = $row['student_nicename'];
$student->classroom_number = $row['classroom_number'];
array_push($obj, array('student' => $student));
// Build a teacher out of the results, push to current object
$teacher = new Teacher();
$teacher->id = $row['teacher_id'];
$teacher->username = $row['teacher_username'];
$teacher->nicename = $row['teacher_nicename'];
array_push($obj, array('teacher' => $teacher));
array_push($rentals, $obj);
}
mysqli_stmt_close($stmt);
return json_encode($rentals);
... building an $obj for each result, and then appending the whole $obj object to the end of $rentals, which is what I pass back in the end. Here is what the response looks like when I encode it to json:
[
[
{
"book":{
"id":113,
"title":"Book Test",
"author":"Test Test Author",
"ar_quiz":1,
"ar_quiz_pts":"10.0",
"book_level":"20.0",
"type":"Fiction",
"teacher_id":1
}
},
{
"student":{
"id":2,
"username":"studentnametest",
"classroom_number":2,
"nicename":"Student Name"
}
},
],
...
]
The problem here is that there is an extra {} around each of the book, student, and teacher objects, causing an extra step when trying to access in the javascript. For example, I think I have to use data[0].[0].book.title, when I really just want to be able to use data[0].book.title. How do I better structure this to fit my needs?
Don't add the additional array structure and you can simply change your array_push lines from
array_push($obj, array('book' => $book));
to
$obj['book'] = $book;
Related
I need looped php data in an html template so I know it has something to do with JSON however not a JSON expert and cannot find much help in searching the web.
$uniqueFranchise_id = array_unique($franchise_id);
$dataArr = '[
{
"name": "Dylan",
"page_link": "https://mypage.com/"
}
]';
foreach($uniqueFranchise_id as $franchise)
{
$sqlFranchise = "select * from franchise where franchise_id = $franchise";
$resultFranchise = $conn->query($sqlFranchise);
if($resultFranchise->num_rows > 0)
{
while($rowFranchise = $resultFranchise->fetch_assoc())
{
$dataArr = json_decode($data, TRUE);
$dataArr[] = "['name'=>'".$rowFranchise['name']."', 'page_link'=>'".$rowFranchise['page_link']."']";
//$json = json_encode($dataArr);
}
}
}
$json = json_encode($dataArr);
print_r($dataArr);
But it only appends one row. In fact it deleteds that data that's already in my dataArr and just adds one row from my loop? Maybe I'm approaching this situation completely wrong?
You set your $dataArr inside the while-loop. So each time the loop is runs, it will be overwritten. Also, it makes more sense and it's much more clear when you handle it as an array (or object) and afterwards convert it to JSON.
$dataArr = array(array('name' => 'Dylan', 'page_link' => 'https://mypage.com/'));
foreach($uniqueFranchise_id as $franchise)
{
$sqlFranchise = "select * from franchise where franchise_id = $franchise";
$resultFranchise = $conn->query($sqlFranchise);
if($resultFranchise->num_rows > 0)
{
while($rowFranchise = $resultFranchise->fetch_assoc())
{
$dataArr[] = array('name' => $rowFranchise['name'], 'page_link' => $rowFranchise['page_link']);
}
}
}
$json = json_encode($dataArr);
echo $json;
You shouldn't be building the string up by yourself, you should build the data and then JSON encode the result (comments in code)...
$dataArr = '[
{
"name": "Dylan",
"page_link": "https://mypage.com/"
}
]';
// decode existing JSON to start array
$dataArr = json_decode($data, TRUE);
foreach($uniqueFranchise_id as $franchise)
{
// Read just the data you need from the table
$sqlFranchise = "select name, page_link from franchise where franchise_id = $franchise";
$resultFranchise = $conn->query($sqlFranchise);
if($resultFranchise->num_rows > 0)
{
// Read all of the rows into an array
$newData = $resultFranchise->fetch_all(MYSQLI_ASSOC);
// Add in existing data
$dataArr = array_merge($dataArr, $newData);
}
}
// Now encode the list of elements into 1 string
echo json_encode($dataArr);
You should also look into prepared statements if this data is not trusted to stop SQL injection.
I read user from the database but I return json to ajax only return the last user because I cant concatenate the json encode.
$myObj = new \stdClass();
while ($fila = $bd->fila()) {
$myObj->NOMBRE = $fila["NOMBRE"];
$myObj->ROLENAME = $fila["ROLENAME"];
$myObj->IDUSER = $fila["IDUSER"];
$myJSON = json_encode($myObj);
}
echo $myJSON;
You are now overwriting $myJson in each iteration. We can also not "concatanate" two jsons (well, we could, but we shouldn't, cause it's laborious..).
Better put everything in one array/object and json_encode() at the very end.
$myObj = new \stdClass();
$users = array(); // instantiate a new array
while ($fila = $bd->fila()) {
$myObj->NOMBRE = $fila["NOMBRE"];
$myObj->ROLENAME = $fila["ROLENAME"];
$myObj->IDUSER = $fila["IDUSER"];
// add objects to that array
$users[] = $myObj;
}
// then at the end encode the whole thing to json:
echo json_encode($users);
Now here are some variants:
If you want everything that your db is returning in this items you could shorten that to:
$users = array(); // instantiate a new array
while ($fila = $bd->fila()) {
// add the whole item (cast as Object) to that array
$users[] = (Object) $fila;
}
// then at the end encode the whole thing to json:
echo json_encode($users);
If you don't care if the items are objects or arrays you could skip the casting and just add the array to the big array:
$users[] = $fila;
Maybe if you concatenate it as array like this
$myJSON[] = $myObj;
and then after the while
echo json_encode($myJSON);
You just have to collect data to big array and then encode whole array. Also there's no reason for creating new StdObjects instead of usual arrays.
// define empty array
$result = [];
while ($fila = $bd->fila()) {
// add to the array all needed elements one by one
$result[] = [
'NOMBRE' => $fila["NOMBRE"],
'ROLENAME' => $fila["ROLENAME"],
'IDUSER' => $fila["IDUSER"],
];
}
// encode whole result
echo json_encode($result);
I'm pulling data from JSON array in php.
Everything works as expected but somewhere in the loop parts gets lost, it only pulls first one.
Please help.
Thank you very much.
Here is Json:
$json = '
{
"theId": "fB17",
"loadId": "82387T",
"description": "Short description",
"contact": "Name of person",
"contactinfo": "Phone number or email of contact person",
"pickupaddress": "Address",
"parts": [
{ "number": "655-2032B" },
{ "number": "655-2056" },
{ "number": "655-2056" },
{ "number": "300-85091" }
]
}';
PHP code:
$data = json_decode($json);
$theId .= $data->theId;
$loadId .= $data->loadId;
$description .= $data->description;
$contact .= $data->contact;
$contactinfo .= $data->contactinfo;
$pickupaddress .= $data->pickupaddress;
ALL ABOVE GET PULLED FROM JSON AND SAVED PROPERLY
Saving data
$obj = new ElggObject();
$obj->subtype = "load";
$obj->description = strip_tags($description);
$obj->title = $title.$theId.'-'.$loadId;
$obj->contact = $contact;
$obj->contactinfo = $contactinfo;
$obj->pickupaddress = $pickupaddress;
$guid = $obj->save();
Object is saved with basic info
Now going through "parts" data from Json
foreach ($data->parts as $core_title) {
// Getting "parts' value from Json
$titlename = $core_title->number;
//Now need to use that data and find existing entity with that title in Database
$dbprefix = elgg_get_config('dbprefix');
$options['joins'][] = "JOIN {$dbprefix}objects_entity oe ON oe.guid = e.guid";
$options['wheres'][] = "oe.title = '$titlename'";
$options['types'] = array('object');
$options['subtypes'] = array('core');
$options['limit'] = 1;
$entity = elgg_get_entities($options);
// I got that entity that matches the title
//Now get GUID of the entity
foreach ($entity as $o) {
$boxg = $o->guid;
}
// It works I get the GUID as $boxg but now need to save EACH $data->parts as annotation to database
$obj->annotate('cores', $boxg);
}
IT only grabs first one fron Json ( 655-2032B )and saves only that one.
If I do this it saves each $data->parts value not just first one:
foreach ($data->parts as $core_title) {
$titlename = $core_title->number;
$obj->annotate('cores', $titlename);
}
This code makes no sense:
//Now get GUID of the entity
foreach ($entity as $o) {
$boxg = $o->guid;
}
It goes through all items in $entity and keeps overwriting $boxg value without actually doing anything with the value.
The result of this foreach loop is that $boxg holds the GUID of the last item in $entity and only then this one single value used to annotate:
$obj->annotate('cores', $boxg);
Is this what you really wanted to do? Shouldn't the annotate method be used inside the foreach loop?
Apart from that it's hard to give you a clear answer because your code is rather obscure and not well explained.
Figured it out finally.
It was not foreach but what was in it.
Ended up making function that does database query to find existing entity with that title.
This is what I ended up with.
Thanks everyone for the help.
foreach ($data->parts as $core_title) {
$titlename = $core_title->number;
$entity = get_object_by_title('core',$titlename);
foreach ($entity as $o) {
$coreguidd = $o->guid;
$obj->annotate('cores', $coreguidd);
}
}
Hello Stackoverflow community, i'm little bit confused how i can achieve this. So this is how my json response should look:
some_array: [
{
some_json_object_atribute_1:
some_json_object_atribute_2:
// Here i need an array
json_array: [
]
}
{
some_json_object_atribute_1:
some_json_object_atribute_2:
}
]
But i'm only getting one row from json array. This is some part of the code:
$response["chat_rooms"] = array();
while ($chat_room = $result->fetch_assoc()) {
$tmp = array();
$tmp["chat_room_id"] = $chat_room["chat_room_id"];
$unread_messages = $db->getAllUnreadMsgsFromChatRoom($user_id, $chat_room["chat_room_id"]);
while ($unread_message = $unread_messages->fetch_assoc()) {
// Here i need one json array
$tmp["message_id"] = $unread_message["message_id"];
}
array_push($response["chat_rooms"], $tmp);
}
You are overriding $tmp["chat_room_id"] in every run of the while loop.
The right syntax would be:
$tmp["chat_room_id"][] = $unread_message["message_id"];
or
array_push($tmp["chat_room_id"], $unread_message["message_id"]);
This works when we do this:
$db = $connection->messages;
$collection = $db->messagesCollection;
$messageArray = $collection->find(array('IDto' => '4'));
foreach($messageArray as $messageData){
$messageFrom = $messageData['IDfrom'];
$messageTo = $messageData['IDto'];
$messageTitle = $messageData['messageTitle'];
$messageIfRead = $messageData['ifRead'];
}
$JSONData = array('true', $messageFrom, $messageTo, $messageTitle, $messageIfRead);
echo $_GET['callback']."(".json_encode($JSONData).")";
But when we do this:
$db = $connection->messages;
$collection = $db->messagesCollection;
$messageArray = $collection->find(array('IDto' => '4'));
$JSONData = array('true', $messageArray);
echo $_GET['callback']."(".json_encode($JSONData).")";
and in the Javascript do this:
$.getJSON("mySite.com/pullData/getMail.php?callback=?",{
request: requestVar},
function(recievedData) {
alert(recievedData);
})
We get an alert of true, [object Object]
When using console log we get Object {}
How do we send that table data correctly?
I believe your biggest problem is the MongoCursor:
$messageArray = $collection->find(array('IDto' => '4'));
$JSONData = array('true', $messageArray);
echo $_GET['callback']."(".json_encode($JSONData).")";
You are trying to encode an object of MongoCursor there, hence the string representation is [object Object].
Try:
$messageArray = $collection->find(array('IDto' => '4'));
$JSONData = array('true', iterator_to_array($messageArray));
echo $_GET['callback']."(".json_encode($JSONData).")";
Instead. All find functions in MongoDB return a MongoCursor, the reason why your first code works is because you iterate the cursor building up your objects:
foreach($messageArray as $messageData){
$messageFrom = $messageData['IDfrom'];
$messageTo = $messageData['IDto'];
$messageTitle = $messageData['messageTitle'];
$messageIfRead = $messageData['ifRead'];
}
Note as well that the default json_encode of a document will contain objects, such as MongoId and MongoDate that do not encode too well into reusable JSON syntax. As such you will need to handle these types yourself.
Edit
Maybe a better way is to actually redo the indexes manually:
$messageArray = $collection->find(array('IDto' => '4'));
$d = array();
foreach($messageArray as $row){
$d = $row;
}
$JSONData = array('true', $d);
echo $_GET['callback']."(".json_encode($JSONData).")";
This way you will have a 0 based incrementing index instead of the ObjectId as each index base.