I'm working on a little posting system so I can post posts on my site and people can like and dislike it.
It looks like this:
At the moment you can upvote and downvote as many times as you would like. I know how to make the images not clickable with JavaScript but I also need a way to do this in PHP because someone could just make the buttons clickable again with fireBug or the Chrome Console.
This is probable the first thing i'm actually making in PHP so i'm still a beginner. Thanks for any suggestions.
I am not going to just write code for you, and there are probably dozens of workable examples on script sites. Here are a few tips to get you pointed in the right direction:
Session variables - $_SESSION[] - Check if it is set, and then set them after a vote. As long as they don't close the browser, they won't be able to vote again.
Cookies - $_COOKIE[] - Same as session, but can remain even if they close and open their browser again.
IP Address - $_SERVER['REMOTE_ADDR'] - Keep a record in a MySQL table of IPs and votes.
Login system - Only allow authenticated users to vote, and then keep track of the votes in the database.
Any combination of the above is acceptable. Hope that gets you pointed in the right direction.
Since you're going to learn this, I'm not going to post any complete code. I can give an overview, though.
The best way to do this is to store votes in a database table (probably MySQL):
| vote_id | user_id | post_id | vote |
Where:
vote_id is an auto-increment column that creates a unique ID for each vote
user_id is an identifier of who the user is that submitted this vote
post_id is an identifier for the post the user is voting on
vote determines whether this vote was up or down.
Now, you can form queries to determine whether or not somebody has already voted on the post, and act accordingly.
You need to validate it on the server-side i.e. in PHP code. You can do that either by IP address (if non-logged in user / guest) or by username (for logged in user)
There is no way you can stop users by client-side validation.
Related
Description:
I am creating comment/reply functionality to a web app that I built. I have a post that I want to link these comments too. To decrease spam and encourage community involvement I want to implement a voting system on each comment/reply.
Problem:
I know how to set up the database and I know how to show upvotes/downvotes. The only thing I don't know what to do is to keep the vote... voted even if the user refreshes the page. I don't want a user to be able to vote up more than once on a single post. Something like the voting on this site, it tracks that you have already voted with a yellow upvote.
What I have thought of:
Place post id in cookie with the user_id appended to it. A simple check of the cookie can stop the user from voting again
Place a unique constraint in table post id... but this is where I get confused. Should I have a separate table just for voted posts? Database schema idea ( I think ) here: https://stackoverflow.com/a/12350981/185672
Keep all the ids in a session array and check against all voted on ids... but that would get huge.
Combination of cookie and database to reduce number of db calls.
In the future there may be 1000s of votes cast by a single user.
edit:
I figured out that storing the results in a database is a must. How can I check for every reply/comment if the user has valid voting privileges without making 1000s of calls?
Resources:
Helped with some further spamming problems, but didn't answer initial question:
https://stackoverflow.com/a/2333085/185672
Old solution that explains how to count votes but not keep the "upvote" checked.
http://www.9lessons.info/2009/08/vote-with-jquery-ajax-and-php.html
Bonus question:
If you guys know of a great script that can allow me to sync up a commenting system ( with votes ) into my already built app?
Also, I tried to find duplicates, but I just can't.
Yeah, just keep a separate table to track user votes. Since you know which user is requesting the page, you can easily join the votes table to determine the current user's eligibility to vote on each post on the page. For each post, if they're eligible, output one version of html, if they're not then output another.
Once the ajax request asks for the php file that does the vote, you can then check once more that that user is eligible to vote - I.e they're changing their vote, or they haven't voted before.
Take yahoo's news stories for example - when you request a page that you've made a comment on, your own comment has disabled voting buttons. With some hacking of the page inside the browser's dev tools, you can enable the buttons. You can even click on them and vote for your own post - though only once.
So, you can see that they got 2/3rds of it right, and output html based on the user's eligibility to vote. They also prevent multiple voting (server-side), they just don't do a server-side check to ensure you're not voting for your own comment.
Stack Overflow on the other hand, always shows the same html - but when you click to vote for your own comment, the server-side code baulks at the idea and the response is basically 'bugger-off! you can't do that' having received a negative result from the server, the javascript on the page pops up the message, rather than updating the vote count.
I suggest you create a "hidden field" in your page that stores information about the upvote/downvote by the user. This is how you would use it:
If the user upvotes/downvotes, the javsvscript on the on the shows the upvote, sets the field to maybe true to indicate the vote status and would also send an AJAX request to the server where the server would record the vote status in the user profile database.
Then whenever the post is re-loaded for a particular user, the server sets the hidden field server-side to true or false, depending on the vote record that is stored in the database. The JS would, on load, check the hidden field and set the vote on the page accordingly (you might need an extra hidden field to indicate whether it is an up or down vote).
I want to set up a voting system which doesn't require people to log in, but they can vote as they want.
How do i stop people from spamming on voting (sending request to add the vote)? i know using client site scripting can easily stop it (from proper user), but what about server side (PHP). i don't want people to have that url and constantly hit it to increase the number.
Cheers
Implement reCAPTCHA - it's super easy to implement (takes maybe 10 minutes), is a good anti-spam measure, and serves a greater purpose (digitising books).
If you really want to go with cookies, have a look into evercookies. They're super-invasive, and very unethical, but hey, it's your site :)
You'll have to log their IP and/or set a cookie. The problem with cookies is the client can erase them and the problem with IP tracking is it can block more than one user if a NAT firewall is in the mix, but it will do well for the most part.
You can add a vote_tracking table:
vote_tracking
id
poll_id
session_id
When a user votes in a specific poll, you can update the row with their session id.
You will then need to implement some code to ensure you don't keep issuing queries to determine if user already voted in a poll. If you have an 'active' poll, you can do one lookup, then register a session var indicating that they have already voted, so no matter how many times the poll is rendered, you won't keep hitting the database. Obviously this will only work as long as the current session_id matches, when it differs you will have to issue the first query then reset the session var.
And I'd recommend a reaping mechanism so your table doesn't end up with a million+ rows. If you create a new 'active' poll, truncate the vote_tracking table, or archive it by renaming the table.
Also, the problem with IP tracking is that you will bork users who are behind a proxy, after the first person votes none of the others will be able to vote.
I currently have a website built in PHP, I'm hoping to build a referral system tonight.
My theory is that if I dynamically generate a url and place it on my users' homepage such as
"Referral url = www.mysite.co.uk/referral.php?user=myuser"
Then I could have a script in the page referral.php which gets the username and runs an sql query updating their corresponding row in my table.
The only thing is anybody could then add there own name and sign up multiple accounts.
What is the best way to go about building something like this?
Thanks
Suppose to get the referral url my users had to click a button which generates the referral url as a rand ie mysite.com/refer.php?user=234234, at the same time storing it in a the db.
Once somebody visits the page refer.php, the referrer then gets his credits or benefit added to his row in the db, at the same time setting his referral code to 0, making the code only available once.
Each time he hits the button on his page, his referal code would change.
Would this be valid do you think?
You generally have the right idea, but protecting against fraud in a referral system is difficult. You can check for unique IP addresses in $_SERVER and add that to the database for each request, throwing away duplicates or limiting referrals from IP addresses that don't come from the user who signed up. Like HTTP_REFERRER, this can be spoofed as well with ease (using TOR for example).
It's a tough problem that isn't something you can truly "solve." Like most fraud cases, you can only do your best to mitigate the effect.
EDIT TO ADD: You can also require referrals to "mature" by forcing the referred user to be active on the site for a defined period of time (say, 30 days) to increase the effort of spammers/cheaters. But again, this doesn't "solve" the problem - all you can do is make it tougher for them to game the system. And occasionally, by doing this stuff, you can ruin user experience. So how do you balance it? Tough question. :)
EDIT TO ADDRESS YOUR EDIT: Contemplate the following scenarios if we implement your plan:
1) I click the button and get my code. Then I paste it to... who exactly? One person? That's not particularly good for sharing on Facebook, MySpace (does this exist?), or my personal blog. I have to generate a referral code for EVERY person I send to the site? That not only scales terribly, but is a horrible user experience as well.
2) Let's say I figure out what you're doing. I develop a bot that clicks that button 4 trillion times. What now?
You could use the 'HTTP_REFERER' value to check what page the request came from, and only allow votes for that user from their page. This can be spoofed, but most people won't know how.
You can count the referral points for some additional action on your site, for example registration or payment or anything that is behind captcha check.
But do not build any obstacles for your regular legit users!
you could embed this information in the POSTDATA - it's a tad more secure.
Or you can add a restriction that any user may be upvoted ONLY by any other EXISTING user only once. And to make it more "secure", generate userIds with a random seed.
in my application a user can post his/her article that other users can response upon ans vote up and down also like stackoverflow has for posted question ans answers.
How can I restrict user so that he/she can't vote twice ?
Just store user id in the voting table.
So, you can always check if particular user already voted.
article-id, user-id, vote time and vote value columns is enough
Two methods:
Client Side: Set into cookie (article IDs for last 5 or 10 votes ) and do not allow to vote again. This is easily hackable but allows you to implement without any database changes!
Server side: track each and every vote up and vote down in a table like <{userID}, {vote UP/DOWN}, {articleID}>
StackOverflow uses database to store all this data. They also lock your vote after some period so you cannot undo your action.
I think the best way to do that is to store all votes and user ids in database, and if it gets bigger you can remove old records from the database after one week/month/etc and restrict voting on items that are older than a week/month/etc, so no one will be able to vote twice on the same item.
You will need to use some kind of server side scripting to remember users by IP or some other unique data. You'll have to store the IP or other data and remember it. When the user tries to up/down vote again, you'll have to check against that to see if you should let them do so. You should let them do the opposite though, in case they want to change their vote. You can do this with PHP and MySQL (and lots of other things).
Whats the best way to keep track of how many users and guests are online? Im making a forum for fun and learning
Right Now I have a 2 fields in the users table called is_online and last_access_time.
If current time is 5 minutes or more than last_access_time i set is_online it to zero. And if the signed in user refreshes browser i set it to 1.
But what about guests? I wanna keep track on how many guests are on also
Another thing that would be really cool is to show what page the user is viewing. and on the page, forum thread for example, 5 guests, Homer and Shomer are viewing this page. But how should i structure this? Hmm maybe i should make another question for that.
i dont know what i should do
What do you suggest?
I'd use cookies for this. Set a cookie when the user enters (checking first to make sure one doesnt exist). Easy way to generate a unique id for that user is to hash their IP plus the current time.
$id = md5($_SERVER['REMOTE_ADDR'] . time());
Store that id in your database and use that to reference
You can check what page they are viewing by grabbing either $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'] near the top of your php source. Store that in the table. I'd take a look at php.net's explanation of whats stored in the _SERVER global, as it should help out quite a bit if you find that you need more then just the document they are on (ex index.php). Found here.
You may need to pull apart of the query string that was used to access that page, parse out the variables to determine the page they are requesting. Either way, this could all be done through cookies, or just use a single cookie to store the unique id and use your table for storing everything else.
You cannot know for certain which page a user is viewing, but you can keep track of which page they last viewed. Every time you deliver a page to a user, record that page's path in a database row associated with them. Voila.
To keep the number of guests, I suggest tracking the number of distinct unauthenticated IP/HTTP-User-Agent combinations seen on a certain page in the last X minutes.
I found this article on Web Monkey that might help you.
http://www.webmonkey.com/2010/02/how_many_users_are_on_your_site_right_now/