I have been working on the header recently. Now I'm end up to create some likes button like Facebook do.
I'm following the PHPacademy on Youtube. The one who's called Alex is really awesome to share what his idea is.
The problem is, I can't show the user name and the product name which to be liked
This is my query:
function plus_the_like($meal_id) {
$meal_id = (int)$meal_id;
$user_name = mysql_query("SELECT `fullname` FROM `users` WHERE `user_id` = (".$_SESSION['user_id'].")");
mysql_query("UPDATE `meal` SET `likes_meter` = `likes_meter` + 1 WHERE `meal_id` = $meal_id");
mysql_query("INSERT INTO `likes` (`user_id`,`user_name`, `meal_id`) VALUES (".$_SESSION['user_id'].", $user_name, $meal_id)") or die(mysql_error());
}
I know what I am doing wrong just on my query, but ahh... When I'm using the SQL in MySQL all works so well:
SELECT `fullname` FROM `users` WHERE `user_id` = 1
And that query can show me what is the username with the user_id 1
I hope that I can put that username from users table into likes table
Here is what you should be doing.
You have a users table with the following information
id - this is a unique ID of the user, this should be marked as a primary key. Auto incrementing.
Keep whatever else information you want on the user, possibly name, email, etc.
You have an articles table (or whatever your likes are based off of.
id - this is a unique ID of the article, this should be marked as a primary key. Auto incrementing.
Store whatever information you want on your articles, or your items in a store or whatever it is you want to "like".
You have a likes table.
id - this is a unique ID of the like, this should be marked as a primary key. Auto incrementing.
user_id - this is a unique ID of your user that clicked the like button, should be marked as a foreign key.
article_id - this is a unique ID of your article that was "liked", should be marked as a foreign key.
With this, whenever a user "likes" an article, you would have a query like
INSERT INTO likes (user_id, article_id) VALUES (:userID, :articleID);
and to count the number of likes on a given article, you would do something like
SELECT count (user_id) FROM likes WHERE article_id = :articleID;
This will allow you to track how many likes for each article, as well as what each user liked. Potentially, you could eventually suggest things to users based on what they have liked. Though, that is a lot more work to do.
This is a very basic version of what you are attempting to accomplish. As people in the comments have said, look into properly sanitizing your database input. If nothing else, at least change to my_sqli_* if you do not have PDO access. PDO is the suggested way to go though, if you are not going to use a framework that gives you all of this.
Related
I would like to link two SQL tables together, both the tables have data entered in them through HTML/PHP forms.
The first table is where the user enters all their details into a form (called system), and the second table is for where a user fills out another form for booking (called users). How do I link these tables together? To show the users booking(s).
I don't know how to get the booking table/form to echo out the user's username into the second table to link them together?
I understand that this does not make sense but would really appreciate some help!!!
Here is the first table's SQL for creating a user account:
And, here is the SQL for creating a booking?:
</form>
</body>
</html>
<br></br>
</div>
</div>
</div>
</body>
</html>
Here is the code that links what the user entered for the booking form (system table) to the SQL database.
Two tables can be "linked" together using JOIN. If you want to list the bookings (rows in the details table), with some user information, you can use LEFT OUTER JOIN or INNER JOIN. (The difference is that with LEFT OUTER JOIN you get all the bookings even if some of them don't have a user. With INNER JOIN you get only the bookings where there exists a corresponding row in users.)
If a column has the same name in two different tables, you can use users.user_uid and details.user_uid to refer to them.
SELECT details.*, user.email, user.first, user.last
FROM details LEFT OUTER JOIN user ON user.user_id = details.user_uid;
Then you maybe want to add a WHERE or ORDER BY and perhaps a LIMIT.
In the users table, there is a user_id (INT) and a user_uid (VARCHAR). The details table has a user_uid (INT). In the example, I was assuming that the user_uid in the details table corresponds to the user_id in the users table because these are both INT. You might want to change the name of some column to make it less confusing. Let's assume you want to rename users.user_uid to "username".
Also, you should add a unique index on the user_id and username, assuming that you want both of them to be unique. For the INT, I suggest you make this the primary key with automatically incrementing numbers and the username, just a unique key:
CREATE TABLE users (
user_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
... ,
username VARCHAR(20) NOT NULL UNIQUE,
...
);
In the details table you probably also want to make the ID a PRIMARY KEY with AUTO_INCREMENT.
A unique key guarantees that there are no duplicates and it also makes lookups on these columns efficient.
If you are just trying to query them together a join should do the trick.
SELECT users.user_first, users.user_last, users.user_email, system.* FROM system INNER users JOIN ON users.user_uid = system.user_uid
In order to store the user_uid value in the system table you need to add a hidden input in your form like this:
<input type="hidden" name="uid" value="<?php echo $_SESSION['u_id']; ?>">
then in your php add
$user_uid = $_POST['uid'];
and insert it when you run your insert query.
INSERT INTO system (date, time, table_layout, user_uid) VALUES ('$date', '$time', '$table_layout', '$user_uid');
Just make sure that your table actually has that column. Once that value is available you should be able to run the above join query.
Let's see. You have two tables, one with user data (users), and one with booking data (details). A "details" row contains an ID of the user linked to that particular row.
Once you know, at least, the ID of the booking, you can get the id of the user like this:
SELECT user_uid FROM details WHERE ID = #specificBookingID
Once you know the user id you can get the user data:
SELECT * FROM users where user_uid = #retrievedUserID
You can do it in one query like so:
SELECT * FROM users where user_uid IN (SELECT user_uid FROM details WHERE ID = #specificBookingID)
How would I set up a table for topics that a user likes? I have a topics tables and a user table (more actually but simplified for a post on here). There is an ever increasing number of topics as they are user generated, how could I allow users to like pages? Would i put the topic's id in the user table or the user's id in the topics table or a create a new likes table? The issue I see is that the number of topics could (potentially) be very large. What could I use to create a system that allows a relationship between a users id and the topics id?
What you could possibly do is a "many to many" table structure
A unique auto incremented id - UINT (10) AUTO_INCREMENT
A feild containing the user id - UINT (10) (or what ever matches your main user_id field)
A field containing the "liked" topic id - UINT (10) (or what ever matches your main topic_id field)
Both user_id and topic_id fields would need to be unique together. That means that there can only be once row for a specific like per user. This makes sure (on the database side), that a user will not be allowed to like a topic more than once.
Getting a users liked topics would look like this -
SELECT * FROM user_likes` WHERE `user_id`=USER_ID
Getting the users per like would look like this -
SELECT * FROM user_likesWHEREtopic_id`=TOPIC_ID
As others have said in their answers and also #trevor in the comments below -
Don't forget to add an index on the userid to support retrieval of user liked topics and a separate index on topic is to support the topics per user query - without these, the queries will get slower as more data is added over time.
One way to do it is to create a new table UserLikedTopics or something similar, in which you have two columns, one to keep the UserId and one to keep the TopicId. For each new topic a user "Likes", you add a new row to the table with the UserId and the TopicId. That way it is easy to keep track of which users likes which topics.
To get whoch topics a certain user like, you simply join the UserLikedTopics with your topics table, and you have a list of all topics a certain user like. You could also make it the other way around and join it on the User table, to get a list of the users that like a certain topic.
You will need a 'likes' table. Something like:
CREATE TABLE `users_likes` (
`user_id` INT(10) UNSIGNED NOT NULL,
`topic_id` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`user_id`, `topic_id`),
INDEX `topic_id` (`topic_id`)
)
Create a separate likes table since it's a separate entity,
link the likes table with users & topics table with userid & topicsid as foreign keys in likes table..
It would be good to have a structure like this, later if you dont even want a feature likes, can just remove it without affecting other tables...
Okay i'm creating a little community website. A user joins my site and he has the option to
enter his informations upload photos add friends and post to his wall. By now i want to know how to implement the album table.
The album has the following attributes:
albumID
albumName
albumCover
albumDescription
albumDate
albumPrivacy enum
userID
username
Now i want to know how to link albums table with the users table. Every user has its ID and username. The usersId is primary key and the username is unique.
1 user can have many albums. 1 album can belong to only 1 user.
How can i do relationships ???
Help please because im not that good at databases and i want to get things done in optimized and secured way.
By now i use usersid and username as attributes in albums table to identify which album belongs to who. like this SELECT * FROM albums WHERE userid='$userid' AND username ='$username'. Where $userid is value from session variable and $username is value from session variable.
Is username in the Users table? If so, then you don't need to worry about including it in the Albums table, too.
The usersId is primary key and the username is unique.
Just to clarify, the userID should be a primary key on the Users table, but a foreign key on the Albums table (as matthewh mentioned). "albumID" is the column that should be the primary key for the Albums table.
Your SELECT SQL can also be simplified, as you should not need username in your WHERE clause. I'm going to assume that users can't have multiple usernames, so only stating userID in your WHERE should be sufficient.
However, if you still want to see username in your Albums result set, you can do this:
SELECT a.*, u.username
FROM albums a
INNER JOIN users u ON u.userid = a.userid
WHERE a.userid='$userid';
Also I feel compelled to mention that you should really parameterize your SQL statement (in your PHP code) instead of concatenating your SQL command string together. That will protect it from SQL injection attacks. It's a bigger danger with user input, so using a session variable should be ok. But it's still a good habit to get into.
The way you've done it is pretty much right. You only need to have the userID column in the album table, because it is a primary key in the user table and thus guaranteed to be unique. Having the username column in the album table is redundant.
You just need to make sure the userID column in the album table is defined as a FOREIGN KEY and of course has an index applied to it.
Ok so a user comes to my web application and gets points and the like for activity, sort of similar (but not as complex) as this site. They can vote, comment, submit, favorite, vote for comments, write description etc and so on.
At the moment I store a user action in a table against a date like so
Table user_actions
action_id - PK AI int
user_id - PK int
action_type - varchar(20)
date_of_action - datetime
So for example if a user comes along and leaves a comment or votes on a comment, then the rows would look something like this
action_id = 4
user_id = 25
action_type = 'new_comment'
date_of_action = '2011-11-21 14:12:12';
action_id = 4
user_id = 25
action_type = 'user_comment_vote'
date_of_action = '2011-12-01 14:12:12';
All good I hear you say, but not quite, remember that these rows would reside in the user_actions table which is a different table to the ones in which the comments and user comment votes are stored in.
So how do I know what comment links to what row in the user_actions?
Well I could just link to the unique comment_id in the comments table to a new column, called target_primary_key in the user_actions table?
Nope. Can't do that because the action could equally have been a user_comment_vote which has a composite key (double key)?
So the thought I am left with is, do I just add the primary keys in a column and comma deliminate them and let PHP parse it out?
So taking the example above, the lines below show how I would store the target primary keys
new_comment
target_primary_keys - 12 // the unique comment_id from the comments table
user_comment_vote
target_primary_keys - 22,12 // the unique comment_id from the comments table
So basically a user makes an action, the user_actions is updated and so is the specific table, but how do I link the two while still allowing for multiple keys?
Has anyone had experience with storing user activity before?
Any thoughts are welcome, no wrong answers here.
You do not need a user actions table.
To calculate the "score" you can run one query over multiple tables and multiply the count of matching comments, ratings etc. with a multiplier (25 points for a comment, 10 for a rating, ...).
To speed up your page you can store the total score in an extra table or the user table and refresh the total score with triggers if the score changes.
If you want to display the number of ratings or comments you can do the same.
Get the details from the existing tables and store the total number of comments and ratings in an extra table.
The simplest answer is to just use another table, which can contain multiple matches for any key and allow great indexing options:
create table users_to_actions (
user_id int(20) not null,
action_id int(20) not null,
action_type varchar(25) not null,
category_or_other_criteria ...
);
create index(uta_u_a) on users_to_actions(user_id, action_id);
To expand on this a bit, you would then select items by joining them with this table:
select
*
from
users_to_actions as uta join comments as c using(action_id)
where
uta.action_type = 'comment' and user_id = 25
order by
c.post_date
Or maybe a nested query depending on your needs:
select * from users where user_id in(
select
user_id
from
users_to_actions
where
uta.action_type = 'comment'
);
On my website, I have a table movies and a table users
I'm trying to have an "Add to favs" button that a user can click, which will add that movie to his favorites (ajax / javascript not necessary at the moment, just php).
So what's the simplest way I could do something like that? I've thought about this but I can't seem to find a solution (all I think of is way too complicated, and in my opinion not possible).
What's your thoughts?
I don't need a ready-made script, just an idea that could get me working (although if you have an example of such script, I'd be happy to look at it).
Thanks!
This is a many-to-many relationship. A user can favorite many movies, and a movie can be favored by many users. In an RDBMS, you represent a many-to-many relationship with a third table. I call this an intersection table but it goes by other names too.
Create a table with two columns. The columns are both foreign keys, referencing movies and users, respectively.
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
When a user chooses to favorite a movie:
INSERT INTO Favorites (user_id, movie_id) VALUES (?, ?)
When a user decides they don't like a movie any longer, delete the corresponding row:
DELETE FROM Favorites WHERE (user_id, movie_id) = (?, ?)
To get the set of movies favored by a given user:
SELECT movie_id FROM Favorites WHERE user_id = ?
To get the set of users who favor a given movie:
SELECT user_id FROM Favorites WHERE movie_id = ?
Regarding one of your comments:
You shouldn't make the "Add to favorite" a link. Indexers like Google will follow links, and then before you know it, every user has favorited every movie.
The general best practice is that read-only operations can be GET requests, while operations that write to the database can be POST requests. This means that you need to use a <form> element to submit POST requests, not an <a href="..."> element.
Add a third table:
CREATE TABLE user_favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY user_id REFERENCES users (user_id),
FOREIGN KEY movie_id REFERENCES movies (movie_id)
)
This is called an intersection table or join table, as it joins rows in the users table to rows in the movies table (as you see, each column is a foreign key). It is also defines a many-to-many relationship, because one user can like many movies and one movie can be liked by many users.
When you go to add a favorite movie for a user, all you have to do is insert a row in this table with the ID of the user and the ID of the movie:
INSERT INTO user_favorites(user_id, movie_id) VALUES([user ID], [movie ID])
To see what movies a user has favorited:
SELECT movie_id FROM user_favorites WHERE user_id = [user ID]
You will need to create a new table:
user_favorite_movies
--------------------
ID (primary key)
userID (foreign key)
movieID (foreign key)
date
Then when the user clicks the 'Add Favorite' button, you just insert a new row into user_favorite_movies with the users ID from the user table, the movie id from the movie table, and the date it was added (good for sorting later).
Hope this helps!
Best,
-Eric
You could create a table favourites with three columns, id, mid and uid. To add a favourite:
INSERT INTO favourites (mid, uid) VALUES (3, 5)
To search for favourites of one user:
SELECT * FROM favourites WHERE uid = 7
To search for people who favourited one movie:
SELECT * FROM favourites WHERE mid = 9
So far as I can see, you'll still need to use JavaScript or Ajax to do the post, unless you want to refresh the page every time thet mark/unmark a favorite, and also to add/remove the new favorite indicator in place at the same time.
Or am I missing something?