This issue relates to losing data due to conflicting column names in a JOIN. Specifically, using PHP's mysqli and returning the data as a JSON object.
Let's say you have two tables that are related to each other using another lookup table.
For example, let's say you have users:
user
id name
---------------------
1 John Thomas
and recipes:
recipe
id name
---------------------
15 Fried Chicken
and ownership/rights to these recipes is defined in a lookup table:
user_recipe
user recipe
--------------
1 15
So, in this case, John Thomas has rights to view the Fried Chicken recipe.
Let's say you want to get a record with all of this data, so you construct a query like this:
SELECT *
FROM `user_recipe`
INNER JOIN `recipe`
ON `recipe`.id = `user_recipe`.recipe
INNER JOIN `user`
ON `user`.id = `user_recipe`.user;
Now let's also say you're using PHP's mysqli object. Then you use json_encode and hand the data back to your javascript. Great! Except that the data looks like this:
{
id:15,
user:1,
recipe:15,
name:"Fried Chicken"
}
How do you resolve this issue? You could use aliases, but what if there are a lot more columns and you don't want to have to write them all out?
If you make use of mysqli's method fetch_fields, you can separate the data back into groups, or add prefixes to the field names, or whatever else you'd like.
Here's an example:
$sql = '...QUERY...';
$mysqli->query($sql);
$fields = $result->fetch_fields();
$output = array();
while ($row = $result->fetch_array())
{
$newoutput = array();
foreach($row as $key=>$value)
{
if (is_numeric($key))
$newoutput[$fields[$key]->table][$fields[$key]->name] = $value;
}
$output[] = $newoutput;
}
$result->free();
echo json_encode($output);
After doing that, the data will be handed back in this format:
{
user_recipe:{
user:1,
recipe:15
},
user:{
id:1,
name:"John Thomas"
},
recipe:{
id:15,
name:"Fried Chicken"
}
}
Of course, you can build the JSON object however you'd like.
Related
I'm trying to return a JSON object with a Key,Value pair, both of which are seperate columns in my MySQL table.
So the MySQL table Looks (simplified 1000%) like this:
+-----------------+---------------------+
| Email | ProfilePicture |
+-----------------+---------------------+
| john#email.com | https://someurl.com |
| jane#email.com | https://foobar.com |
| bobby#email.com | https://random.com |
+-----------------+---------------------+
And I want a JSON object like
{
"john#email.com":"https://someurl.com",
"jane#email.com":"https://foobar.com",
"bobby#email.com":"https://random.com"
}
I could build it up as a string in MySQL by looping through the table and concat everything together, then just parse it in JS. I know that. But it seems messy, and I know there must be some built in functions for this in PHP. I just don't know them.
All my other PHP/MySQL pairings are using mysqli_fetch_assoc and json_encode in the PHP as they don't need the JSON Key to change dynamically only the value.
The eventual JSON object is being returned from a JavaScript function, so I am happy with a fix any where along the chain from JavaScript (or jQuery), to PHP, to MySQL Procedure, and back along.
If you use PDO to connect the database, you can use something like...
$query = $db->query("SELECT Email, ProfilePicture FROM users");
$data = $query->fetchAll(PDO::FETCH_KEY_PAIR);
$out = json_encode($data);
The PDO::FETCH_KEY_PAIR uses the first column returned as the key and the second column as the value.
Sticking to mysqli
$result = $db->query("SELECT Email, ProfilePicture FROM users");
$data = [];
while ($row = $result->fetch_assoc()) {
$data[$row['Email']] = $row['ProfilePicture'];
}
$out = json_encode($data);
MySQLi version - slightly shorter...
$result = $db->query("SELECT Email, ProfilePicture FROM users");
$data = $result->fetch_all(MYSQLI_ASSOC);
$out = array_column($data, 'ProfilePicture', 'Email');
$out = json_encode($data);
So I am trying to send the "id" of a selected row in datatable in javascript to a php page so I could delete it from database.
var ids = $.map(table.rows('.selected').data(), function (item) {
return item[0] });
the variable "ids" is sent by post method
$.post( "deleterow.php", { v1: ids });
but it didn't worked so i try to see the response from post method and it says
"notice array to string conversion in C on line ... "
the line is of php page where i am writing the delete query
$id = $_POST["v1"];
$query = "DELETE FROM `package` WHERE `id` = '$id'";
The whole php page works fine when trying with other values.
Because you send an array here:
$.post( "deleterow.php", { v1: ids });
so v1 contains an array of elements. But in your php code you treat it as a single element:
$id = $_POST["v1"];
Hence the notice array to string conversion.
If you send an array of elements, you have to get it as an array and treat is as an array. To create a correct SQL string you should append each ID, like this:
$ids = json_decode($_POST["v1"]);
$query = "DELETE FROM `package` WHERE";
$first = true;
foreach ($ids as $id) {
if ($first) {
$first = false;
} else {
$query += " OR";
}
$query += " `id` = '$id'"
}
This way you loop the array and append a id = ID for each array element.
Now, this is important, this code is prone to SQL injection, a really bad security problem. Read this to get more info about this: How can I prevent SQL injection in PHP?
i have code above which gets data from a database and then place in in json form to make it readable in java script.
the results of the echo is
"FIAT":["Anglia","Bronco","Capri","Cobra","Consul","Corsair","Cortina"],
"Land Rover":["Defender","Discovery","Discovery 3","Discovery 4"]
I would like the data to be converted in such a way the i can reference it in this form Var Brand=array ();
Brand["FIAT"]=["Anglia","Bronco","Capri","Cobra","Consul","Corsair","Cortina"];
Brand["Land Rover"]=["Defender","Discovery","Discovery 3","Discovery 4"];
in java script. Does Any one know how i can do this.
$query = mysqli_query($conn,"SELECT * FROM car_models");
// Loop the DB result
while(($result = mysqli_fetch_array($query))) {
// Check if this ID is already in the data array
if(!array_key_exists($result['Brand'], $data)){
// Create array for current user
$data[$result['Brand']] = array();
}
// Add the current race time to the array (do not need to use the float)
$data[$result['Brand']][] = $result['Model'];
}
//json data
json_encode($data);
I found the solution. Simply added the json object in a variable and now am able to get the echo it to the console
`
//json data
var brandAvailable =
console.log(brandAvailable);
"`
I tried to build an ajax search bar. It works fine with a single keyword but I can't manage to make it work with 2 keywords...
I was thinking about parsing the data in the input field but my knowledge is limited and I didn't manage to find the solution.
Any ideas?
In my main.js I get the data from the input like this:
var kwVal = $(this).val();
if (kwVal.length < 3){
$(".clothes-container").html("");
}
else {
$.ajax({
"url": "ajax/getclothes.php",
"type": "GET",
"data": {
"kw": kwVal
}
})
And this is my sql request
$sql = "SELECT title, description, picture
FROM outfit
WHERE type LIKE :keyword OR
color LIKE :keyword OR
brand LIKE :keyword OR
material LIKE :keyword";
Thanks a lot.
Something like this? Of course, all the SQL literals and strings must be properly escaped (especially the $keyword).
// keywords extracted from user's input
$keywords = array('blue', 'jeans');
// columns, that You want to match against
$columns = array('type', 'color', 'brand', 'material');
// we build the condition for each keyword
$word_conditions = array();
foreach ($keywords as $keyword) {
$conditions = array();
foreach ($columns as $column)
$conditions[] = $column.' LIKE \'%'.$keyword.'%\'';
$word_conditions[] = '('.implode(' OR ', $conditions).')';
}
// we build the query, that requires every item to have all the keywords
$query = 'SELECT * FROM ... WHERE '.implode(' AND ', $word_conditions);
Suppose your keywords are saperated by 'Space' like "ABC DEF GEH".
than on server you can do is,
$keywords = explode(" ", $_POST['data']); //Make it array;
$string = implode(",", $keywords);
$sql = "SELECT title, description, picture
FROM outfit
WHERE type in (".$string.") OR
color in (".$string.") OR
brand in (".$string.") OR
material in (".$string.")";
I'm trying to set up a comments system on photos.
I understand how to use $.getJSON when the array is like this:
get.php:
$var = 5;
echo json_encode(array('var'=>$var));
main.php:
$.getJSON("get.php",function(data){
number = data.var; // number = 5
});
But I have a more complex thing.
My comments table has these 4 columns: id | photo_id | comment | date
For example let's say we're trying to retrieve the comment data from the photo with
photo_id == 1.
We don't know how many comments there might be.
In getcomments.php:
$photoid = 1;
$comment = mysqli_query($conn,"SELECT * FROM comments WHERE photo_id='$photoid'");
while($commentrow = $comment->fetch_assoc()) {
$comments[] = $commentrow;
}
Then you encode it:
echo json_encode($comments);
Which prints something like this (the photo has 2 comments):
[{"id":"1","photo_id":"1","comment":"text","date":"23858556"},{"id":"2","photo_id":"1","comment":"text","date":"23858561"}]
How do I declare variables for the comments array?
$.getJSON("getcomments.php",function(data){
// how do I declare variables for the comments array, especially since you don't know how many there might be?
});
Additionally, I have two json arrays that need to be echoed within the same PHP file. i.e. echo json_encode(array('img1'=>$img1link)) and echo json_encode($comments); need to be echoed within the same PHP file, but it made the code stop working altogether.
If you want to display the comments you need to loop over the array. You can use for loop or forEach function.
$.getJSON("getcomments.php",function(data){
data.forEach(function(comment) {
$('div').append('<span>' + comment.comment + '</span>');
});
});
To display two JSONs you need to combine them into one JSON object.
echo json_encode(array('img' => $img1link, 'comments' => $comments));
[{"id":"1","photo_id":"1","comment":"text","date":"23858556"},{"id":"2","photo_id":"1","comment":"text","date":"23858561"}]
Using this JSON, data is an array and you should manage it as an array. You can loop through it using simple loops (for, while...) or using new functional methods like forEach, map, filter....
Please try with this example:
$.getJSON("getcomments.php",function(data){
data.forEach(function(item, index, all) {
console.log(item.comment);
});
});
Declare an object, and push it to the array.
var commentsArr = [];
for (var i = 0; i < data.length; i++) {
var objToPush = {
id: data.id,
comment: data.comment,
date: data.date
}
commentsArr.push(objToPush);
}