I have the following tables in MySQL:
recipe: id_recipe (PKey), name_recipe, description
url_pic: id_img, url_img, id_recipe (FKey)
Using PHP, I am trying to get JSON which contains every recipe, along with its pictures' urls (an array). My problem is that the pictures array of recipe 2 includes the pictures of both recipes! I'm a beginner and I can't find where the problem is. I've included below the JSON I want, my PHP code, and the JSON I actually get:
Desired JSON:
[
{
"recette": {
"id_recipe": "1",
"name_recipe": "..",
"description":"..."
},
"pictures": [
{
"id_url": "1",
"url": "picture 1 of recipe 1"
},
{
"id_url": "2",
"url": "picture 2 of recipe 1"
}
]
},
{
"recette": {
"id_recipe": "2",
"name_recipe": "....",
"description": "...."
},
"pictures": [
{
"id_url": "3",
"url": "picture 1 of recipe 2"
},
{
"id_url": "4",
"url": "picture 2 of recipe 2"
}
]
}
]
PHP:
$sql = "SELECT id_recipe,name_recipe,description
FROM recipe";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$data['recipe'] = $row;
$sql2= "SELECT id_url,url
FROM url_img as u
WHERE u.id_recipe = '$row[id_recipe]'";
$result2 = $conn->query($sql2);
if($result2->num_rows > 0){
while($row2 = $result2->fetch_array(MYSQL_ASSOC)) {
$array[] = $row2;
}
$data['pictures'] = $array;
}
$all[] = $data;
}
header('Content-Type: application/json');
echo json_encode($all,JSON_UNESCAPED_UNICODE);
}
Actual JSON:
[
{
"recette": {
"id_recipe": "1",
"name_recipe": "..",
"description":"..."
},
"pictures": [
{
"id_url": "1",
"url": "picture 1 of recipe 1"
},
{
"id_url": "2",
"url": "picture 2 of recipe 1"
}
]
},
{
"recette": {
"id_recipe": "2",
"name_recipe": "....",
"description": "...."
},
"pictures": [
{
"id_url": "1",
"url": "picture 1 of recipe 1"
},
{
"id_url": "2",
"url": "picture 2 of recipe 1"
},
{
"id_url": "3",
"url": "picture 1 of recipe 2"
},
{
"id_url": "4",
"url": "picture 2 of recipe 2"
}
]
}
]
Reset the array in each itteration
$result2 = $conn->query($sql2);
$array = []; // Add this line
if($result2->num_rows > 0){
Related
Essentially I have the following script with the following response:
<?php
header('Content-Type: application/json');
$stmt = $pdo->prepare('
SELECT
`tablelist`.`id`,
`tablelist`.`content`
FROM `tablelist `
');
$stmt->execute([
]);
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
$rowcount = $stmt->rowCount();
if ($rowcount < 1) {
$response["error"] = TRUE;
echo json_encode($response);
}else{
echo json_encode($row);
}
?>
Current Response:
[
{
"id": 1,
"content": "Reason 1"
},
{
"id": 2,
"content": "Reason 2"
},
{
"id": 3,
"content": "Reason 3"
},
{
"id": 4,
"content": "Reason 4"
}
]
I would instead like to present this array as the following (no square brackets):
{
"error": false,
"content": {
"1": "Reason 1",
"2": "Reason 2",
"3": "Reason 3",
"4": "Reason 4"
}
I know I need to do the following:
$response["error"] = FALSE;
$response["content"][$row[id]] = $row[content];
But using this method I am not getting any values from the array.
How can present the values from the array the way?
Look at array_column function and Example #2 at https://www.php.net/manual/en/function.array-column.php
You can transform your rows like this but you must be aware of the uniqueness
$content = '[
{
"id": 1,
"content": "Reason 1"
},
{
"id": 2,
"content": "Reason 2"
},
{
"id": 3,
"content": "Reason 3"
},
{
"id": 4,
"content": "Reason 4"
}
]';
$from = json_decode($content, true);
$to = json_encode(array_column($from, 'content', 'id'), JSON_PRETTY_PRINT);
echo $to;
will result to
{
"1": "Reason 1",
"2": "Reason 2",
"3": "Reason 3",
"4": "Reason 4"
}
via https://3v4l.org/WL29a
You can do it very easily with PDO using the PDO::FETCH_KEY_PAIR fetch mode. It will use the first column from SQL as a key and the second as the value.
<?php
header('Content-Type: application/json');
$stmt = $pdo->prepare('
SELECT
`tablelist`.`id`,
`tablelist`.`content`
FROM `tablelist `
');
$stmt->execute();
$dataFromDB = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
if (!$dataFromDB) {
echo json_encode(['error' => true]);
} else {
echo json_encode(['error' => false, 'content' => $dataFromDB]);
}
This will produce an output similar to this if there were any rows returned from the SELECT:
{
"error": false,
"content": {
"1": "Reason 1",
"2": "Reason 2",
"3": "Reason 3",
"4": "Reason 4"
}
}
I have four tables, ALBUM,ARTIST,SONG,GENRES
ALBUM (ID(PK),ALBUM_NAME,ARTIST_ID(FK),GENRES_ID(FK),ALBUM_POSTER)
SONG (ID(PK),SONG_NAME,ALBUM_ID(FK),ARTIST_ID(FK),SONG_LOCATION)
ARTIST (ID(PK),ARTIST_NAME)
GENRES (ID(PK), GENRES_NAME)
I have created the bellow php file in order to create json file as "desired output" shows, but I have got "actual output" as bellow shows. All songs from all albums are included in each album "song_detail" section as the actual output shows.
php
$sql = "SELECT DISTINCT ALBUM_ID, ALBUM_NAME,ARTIST_NAME,GENRES_NAME,ALBUM_POSTER "
. "FROM ALBUM,ARTIST,SONG,GENRES "
. "WHERE ALBUM.ID=SONG.ALBUM_ID AND SONG.ARTIST_ID=ARTIST.ID AND GENRES.ID=ALBUM.GENRES_ID";
$result = $db->query($sql);
$response["albums"] = array();
if ($result->num_rows > 0)
{
while ($row = $result->fetch_assoc())
{ $album = array();
$album["album_id"] = $row["ALBUM_ID"];
$album["album_name"] = $row["ALBUM_NAME"];
$album["artist_name"] = $row["ARTIST_NAME"];
$album["genres_name"] = $row["GENRES_NAME"];
$album["album_poster"] = "http://www.".$row["ALBUM_POSTER"];
$album['song_details'] = array();
$sql2 = "SELECT*"
. " FROM SONG,ALBUM where SONG.ALBUM_ID = ALBUM.ID";
$result2 = $db->query($sql2);
while ($row2 = $result2->fetch_assoc())
{
$album['song_details'][] = array(
'songName' => $row2["SONG_NAME"],
'song_location' => "http://www.".$row2["SONG_LOCATION"]);
}
array_push($response["albums"], $album);
}
$response["success"] = 1;
}
desired output
[
{
"album_name": "Startboy",
"artist_name": "Weeknd",
"genres_name":"R&B",
"album_poster": "www.yyy.storage.x.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../yw.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
}
]
},
{
"album_name": "25",
"artist_name": "Adele",
"genres_name":"",
"album_poster": "www.yyy.storage.a.png",
"songs_details": [{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}
]
}
]
Actual output
[
{
"album_name": "Startboy",
"artist_name": "Weeknd",
"genres_name":"R&B",
"album_poster": "www.yyy.storage.x.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../yw.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
},
{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}]
},
{
"album_name": "25",
"artist_name": "Adele",
"genres_name":"",
"album_poster": "www.yyy.storage.a.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../y.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
},
{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}
]
}
]
When you are selecting the songs, your SQL doesn't limit which album the tracks are from (although it does make sure they match the ALBUM)...
$sql2 = "SELECT*"
. " FROM SONG,ALBUM where SONG.ALBUM_ID = ALBUM.ID";
You need to just pick the SONG records according to the current album...
$sql2 = "SELECT * FROM SONG where ID =".$row["ALBUM_ID"];
You could use prepared statements here, but as this is using a field from another table it can be used - but not essential.
I am trying to parse a xml to a nested json structure with php.
This is my test script:
$json_drives = array();
foreach($drives->DR as $dr){
$current_drive = array();
$current_drive['id'] = $dr->ID;
$current_drive['name'] = $dr->NAME->D;
$json_drives[] = $current_drive;
}
echo("Finished");
// Parse and save
$f = json_encode($json_drives);
file_put_contents('test12345.json', $f);
I get a structure like that:
[
{
"id": {
"0": "1"
},
"name": {
"0": "Name 1"
}
},
{
"id": {
"0": "2"
},
"name": {
"0": "Name 2"
}
},
// ...
]
But I dont want the keys "id" and "name" to be nested. It should look like this:
[
{
"id": "1"
"name": "Name 1"
},
{
"id": "2"
"name": "Name 2"
},
// ...
]
How can I handle that?
Assuming your JSON's "drive" objects will always have this structure:
"id": {
"0": "Some ID"
},
"name": {
"0": "Some name"
}
You can use:
$current_drive['id'] = ((array) $dr->ID)[0];
$current_drive['name'] = ((array) $dr->NAME->D)[0];
I want to create a JSON format from 3 mysql tables using PHP. Below is my table:
To create a JSON format from these 3 tables I am using this code:
<?php
ini_set('display_errors', 'Off');
$user = "root";
$password = "";
$database = "mydb";
$conn = mysqli_connect("localhost", $user, $password, $database) or die ("Unable to connect");
$sql = "SELECT model_id FROM 1Model";
$sqlRun = mysqli_query($conn , $sql);
$json = array();
$role_model = mysqli_num_rows($sqlRun);
if($role_model > 0){
$i = 0;
while($row = mysqli_fetch_array($sqlRun)){
$row_array= array();
$model_id = $row['model_id'];
$json[$i]['model_id'] = $row['model_id'];
$role_qry = mysqli_query($conn, "SELECT id_cat, cat_name, model_id FROM 1Category WHERE model_id= $model_id");
while($role_fet = mysqli_fetch_array($role_qry)){
$json[$i]['id_cat']['id_cat'] = $role_fet['id_cat'];
$json[$i]['cat_name']['cat_name'] = $role_fet['cat_name'];
$cat_array = array();
$cat_pk = $role_fet['id_cat'];
$test_query = mysqli_query($conn, "SELECT id_item, item_name, id_cat FROM 1Item WHERE id_cat = $cat_pk");
$j = 0;
while($test_fet = mysqli_fetch_array($test_query)){
$json[$i]['item_list']['items'][$j] = array('item_name' => $test_fet['item_name']);
$j++;
}
}
$i++;
}
}
header('Content-type: text/javascript');
echo json_encode($json, JSON_PRETTY_PRINT);
?>
My expected result is json object will filter based on the model name and category name, something like below:
[
{
"model_id": "1",
"cat_name": {
"cat_name": "Box Medium"
"item_list": {
"items": [
{
"item_name": "Box Medium Orange"
},
{
"item_name": "Box Medium Purple"
},
{
"item_name": "Box Medium White"
},
{
"item_name": "Box Medium Grey"
}
]
}
},
},
{
"model_id": "2",
"id_cat": {
"id_cat": "6"
},
"cat_name": {
"cat_name": "Square Large"
}
},
{
"model_id": "3"
}
]
But I don't know why my result children values not filtered based on parent id.
Right now the code encode json as result below:
[
{
"model_id": "1",
"id_cat": {
"id_cat": "3"
},
"cat_name": {
"cat_name": "Box Large"
},
"item_list": {
"items": [
{
"item_name": "Box Medium Orange"
},
{
"item_name": "Box Medium Purple"
},
{
"item_name": "Box Medium White"
},
{
"item_name": "Box Medium Grey"
}
]
}
},
{
"model_id": "2",
"id_cat": {
"id_cat": "6"
},
"cat_name": {
"cat_name": "Square Large"
}
},
{
"model_id": "3"
}
]
Anyone can help me on this, tried to find on the web but unlucky. What I am trying to do is to get a json format hierarchical, model=parent, category=subparent, item=child. Thanks for any helps
I currently have the following table set up:
StartTime EndTime Performer Event Day Location
-----------------------------------------------------
1:00pm 2:00pm Test Test 0 1
11:00pm 12:00am Test Test 0 0
2:00pm 2:30pm Test Test 1 0
11:00pm 12:00am Test Test 2 1
The JSON output looks something like this:
{
"day0": {
"item1": {
"StartTime": "1:00pm",
"EndTime": "2:00pm",
"Performer": "Test",
"Event": "Test",
"Location": 1
},
"item2": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day1": {
"item1": {
"StartTime": "2:00pm",
"EndTime": "2:30pm",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day2": {
"item1": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 1
}
}
}
Since I'm still learning PHP, I wrote some sloppy code by making 3 queries to the database, each time selecting all data where the day was 1, 2, and 3.
Here's an example of code for fetching data for day=0, which is repeated for day=1 and day=2:
echo '{ "day0" : {';
$sql = "select * from table WHERE day = 0";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$rowCount = $result->num_rows;
$index = 1;
while($row =mysqli_fetch_assoc($result))
{
echo '"item'.$index.'":';
echo json_encode(array("StartTime" => $row['StartTime'], "EndTime" => $row['EndTime'], "Performer" => $row['Performer'], "Event" => $row['Event'], "Location" => intval($row['Location'])));
if ($rowCount != $index)
{
echo ',';
}
++$index;
}
echo ' }';
// Repeated code for day=1
// Repeated code for day=2
echo ' }';
I feel as though this can be achieved with just one query, but being that I'm new, I'm not sure how to implement it.
I started to do something like this:
$sql = "select * from table";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$numOfRows = $result->num_rows;
$count = 1;
while($row = mysqli_fetch_assoc($result))
{
$outerIndex = 'day'.$row['day'];
if ($row['day'] == '1')
{
// Do something, not sure
}
if ( !isset( $jsonData[$outerIndex] ) )
{
$innerIndex = 'item'.$count.'';
$jsonData[$outerIndex][$innerIndex] = $row;
}
++$count;
}
echo json_encode($jsonData);
However, I just got stuck, and not really sure how to approach it further.
SQL:
$sql = "SELECT * FROM table ORDER BY Day";
Further down on code:
$result_object = [];
$item = 1;
while ($row = $result->fetch_assoc()) {
if(isset($result_object['day'.$row['Day']]))
{
$result_object['day'.$row['Day']]['item'.$item] = $row;
$item++;
}
else
{
$result_object['day'.$row['Day']]['item1'] = $row;
$item = 2;
}
}
You can then output it with:
echo json_encode($result_object, JSON_PRETTY_PRINT); //JSON_PRETTTY_PRINT is not necessary...
You may disagree with me, but I don't think indexing items with item0, item1 and so on.... or day0, day1 ... is a GOOD idea. I personally prefer that the looping through the result would be:
while ($row = $result->fetch_assoc()) {
if(isset($result_object[$row['Day']]))
{
$result_object[$row['Day']]->items[] = $row;
}
else
{
$result_object[$row['Day']] = (object)['day'=>$row['Day'], 'items'=>[$row]];
}
}
In this case, the result would be an array of objects. ie:
[
{
"day": "0",
"items": [
{
"StartTime": "07:23:56",
"EndTime": "17:24:04",
"Performer": "Performer1",
"Event": "Event1",
"Day": "0",
"Location": "1"
},
{
"StartTime": "09:24:30",
"EndTime": "01:04:37",
"Performer": "Performer2",
"Event": "Event2",
"Day": "0",
"Location": "1"
}
]
},
{
"day": "1",
"items": [
{
"StartTime": "10:25:22",
"EndTime": "11:25:29",
"Performer": "Performer2",
"Event": "Event3",
"Day": "1",
"Location": "2"
}
]
},
{
"day": "2",
"items": [
{
"StartTime": "12:26:08",
"EndTime": "13:26:12",
"Performer": "Performer3",
"Event": "Event4",
"Day": "2",
"Location": "1"
}
]
}
]
The reason: you can easily iterate through each values(an array) in whatever language you're going to use.