I have a PHP website of 6 pages and I want to have a functionality such as this:
The website is a little quiz game where you need to get through 5 trivia questions per page and the final page displays the highscore. The score is based on how fast you got there as the pages have a timer.
But I found out about a cheat I want to fix. If you simply type in the URL highscore.php or question5.php, you can get there faster without having gotten through the first few pages.
Is there some way to fix this?
Track the state of the quiz on the backend, e.g. track which questions have been answered yet. When the user tries to access a page that would require a previous page to be completed first, redirect the user to that page instead.
You can achieve this with a Session.
An even better solution than having six pages would be to have one page instead, e.g. quiz.php and then funnel all access through this page. This will make it easier to track progress because you don't need to copy and paste the code to the individual pages.
On a side note: you also want to track the time the quiz was started on the backend.
It's not that hard, just a careful coding is all you require.
Firstly, start a session and set it to an initial value, say 1, that means the user is in page 1. If he submits the answer, and then the user loads any other page in your website, create a script to call the same session value and use header("Location:page2.php")to force a redirect to page 2 or the page he is supposed to be in.
If the session is removed somehow then use isset() to check if it exists, if it doesn't start from the beginning.
I have seen MANY questions on this before online in many places, however, out of about 30 forums and whatnot, NONE of them have had the solution I need, and that includes stackoverflow. If anyone could help me find a reliable solution, it would be greatly appreciated, so thanks in advance!
I'm going to explain my site and situation with as much detail as possible in order to help any who want to help answer my questions. Here is my situation:
I have a website and I use PHP and MySQL. My website is a "private" organization site. In order to allow people access to the site, I send new members of our organization and invite code. The user then visits the website, and the index.php file simply contains a form for logging in as well as a link to the registration pages. New members click the "Register Here" link to begin registration. The first registration page asks for the user's last name and invite code which are checked against a database to make sure that person is on the list and has not yet registered. If they pass the check, they are taken to the next page in which they enter required information (username & password, email address, etc.) as well as some optional information (phone, bio, etc.). If the user creates a valid username and password and has all required fields filled out, their information is stored in a database. Passwords are all salted and hashed properly and securely, so there is no problem there, and the whole registration process works as it should. After registering, the user is taken back to index.php where they can now log into using the username and password they just created. This works as well; when the user logs in, their username and password are checked against the database, and if successful, the user is logged in. When the user is logged in, an ONLINE value in the database is set from False to True. The user is now logged in and can use the site as it is intended. On my site, there is a column that lists users that are currently online (based on the ONLINE value from the database). When the user clicks the "Log Out" button which is located on every page of the site, the logout.php script is run, ending the session and setting the ONLINE value back to False. This all works fine and dandy, however, the problem comes when the user closes the browser without logging out first. This is where I have seen many different "solutions" various places on the internet. I am going to explain why they won't work and why I need a better solution.
The answers I see most often involve some sort of session timeout or destroying sessions, which is irrelevant because of the fact that the session already does, in fact, end when the user closes the browser, but that has no effect on telling other users whether or not that person is currently online. When the session ends, the database won't be updated, which causes a problem due to the fact that a user can only be logged in from a single instance. If a user attempts to log in while their ONLINE value is already set to TRUE, they aren't allowed to log in.
I have also seen suggestions of using a "Last Seen" value instead of an online value, and if a user hasn't had any activity within the past x amount of minutes, log the user out. This won't work, however, for two reasons. 1) That script still has to be running somewhere in order for that to work, meaning another user must be logged in for that to work. That basically means that, if using this method, if a user closes their browser or if they loose connection, they won't be able to log back in until another user logs in. With my organization being a small, locally based organization as it is, there are likely to be many times in which there are no users online. Also, even if another user is logged in, the user whose connection was lost still won't be able to log back in until after x amount of minutes has passed, so if the user accidentally closed their browser and wanted to log back in immediately, they simply wouldn't be able to.
A less frequent solution I came across involved using the onBeforeUnload JavaScript function, but those most definitely will not work due to the fact that those would trigger any time a user clicked on a link or on the "Back" and "Forward" buttons. Also, if the user has JavaScript disabled in their browser, this will not work at all.
The last thing I have seen involves while loops and the connection_aborted function, and this is the only one that seems like it could work, yet I have not seen a very clear description of how this should work, and after spending months experimenting with it, I still have not come up with a reliable solution.
In many forums, I have seen people say that "it's not possible," but that can't be the case considering there are sites that do it somehow. I have tested and experimented with this on several sites. On a site that has users such as Facebook or any forum website, there is a list of "online" users, and in the case that a user closed their browser, their name would no longer appear on the list, so it is possible, even if it can only be achieved through some obscure method. So, if anyone knows of a solution, I would greatly appreciate if you could share some of your wisdom on this subject!
Try creating a Heartbeat mechanism in javascript.
this method would start sending an ajax call to your webmethod on timely basis use.
setInterval(function(){
sendPulse();
},30000);
sendPulse(){
var varUserID = userID;//any unique user identifier that can be found on server side
$.ajax({
url: "Default.php/updateUserStatus",
UserID: varUserID,
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (mydata) {
//alert("pulse sent");
}
});
}
On server side, you must have a method with same name and case sensitive parameter. the should be static and marked as webmethod. in this method save the current time for the user. you should have a mechanism to know what users have very old pulse, do this check when a user tries to do something or performs any operation. I have implemented this approach and works very well.
That's the answer: persistent connection between client and server. For this, you will need a TCP connection, like websockets nowadays, or a flash old duplex connection. From here on, TCP takes care of noticing you when someone connects or disconnects. What you got to do is a websocket server (for example) who just traks connections (push and pop from an array), and also a way to respond to a "get_users_online" message. You can access your user's session (read only) via the websocket server, and then see if the user is logged-in (and in this way, you can store his nickname in session, access further from websocket server), see if he is admin (session->is_admin).
Pretty simple, I would say.
Here is the library I've been using: http://socketo.me/ . It uses a library for decoding symfony2 sessions, but for simple applications, you don't need decoding (symfony2 applications encodes sessions, so the websocket server has to decode them).
Big note: Sessions has to be stored externally (not in file system /tmp) like a ORM or NoSql.
Either way, escuse me, but I have to say that that the "Last time" seen is super okey. Most of the sites rely on this. You understood something wrong, you don't need to have a living server for checking "Last time" always, when you request /admin.php?users_online=1 , you make a query where "Last seen > NOW() - 5 minutes" (won't work written like that), so you can even get rid of the "ONLINE" "OFFLINE" field.
I suggest using a websocket approach, it's fun. :)
Good luck!
I am building a website in PHP and i need your help. I want to know the time of the user who logged in my site. The task was to store the login time and then the logout time. The login can be stored easily. But for logout there are many ways. The one I can think about are:
By clicking on the logout button.
By Closing the browser.
By letting the session gets expired.
Certainly by disconnecting from internet due to any reason.
I solved my problem for the first three but I don't know how to solve the Fourth one. Then Searching on net I got an idea to implement it using the SERVER PUSH MESSAGE method. In which the server can send message to the client browser after certain interval of time. If he gets a response then it means the user is still connected otherwise user is not connected. I liked the idea but I don't know how to implement this idea because i don't have any knowledge about the push messages.
Please Help.
Thanks in Advance.
From Javascript you shouldcatch the event window.onbeforeunload
I'm not awesome enough to write a chat application, and I'm trying to get one to work, and I've recently downloaded one from here, it's pretty good so far, as I've tested it out on XAMPP, but I have a slight problem. I'm trying to generate a list of online users to give it a more practical application-like feel, but the problem with that, is I have no clue how to do it easily.
When users login to my site, a session named g_username is created, (the chat says 'username', but I'll fix that) and from what I see so far, the easiest method would be to store their username in a database called OnlineUsers and call that data via Ajax, but, the other problem, is that it's session based, and sometimes the users can just leave, without logging out, and I intended to run a script to logout the user from both the OnlineUsers table, and by deleting the session.
If they leave without logging out, they'd be online forever! I could potentially suffix a bit of code on every page, that toggled an ajax event on page close, the event being a script that kills their OnlineUsers table record, but then again, that would load the server with useless queries as users jump between pages, as far as I'm aware.
Creating my entire site in Ajax isn't really an option, as it's a load of different sites combined in to 1 'place' with a social 'layer' (if you will) from a social service.
Does anyone see a way to do this that would make sense, and be easy to integrate, and do with Apache, without command line access?
You could so something like storing a timestamp of the users last action in a database, comparing that timestamp when outputting online users and making sure that it was done at most 1 min ago.
Run on all/vital pages:
(Deciding if the last action is outdated, you could also check if it was done for one minute ago to reduce the database-load)
if($user['lastAction'] < time()) {
//update into database, last action is outdated
}
When calculating the amount of users online and is within the loop of each timestamp
//If the users last action was within a minute, the user is most likely online
if(($row['lastAction']- time()) > 60*60)
//count user as online
you could have a cron job [if you have cpanel] running on the server once every 60secs or so, that checks when a user last sent anything via the chat if they have not in the last lets say 5mins then remove their entry from the online users list.
I'm currently building a website which fetches youtube videos and flickr images and lets users comment on them on the website. While having it's own commenting system, the website also has an option to login with youtube/flickr to comment on youtube or flickr with their usernames.
I'm doing this by opening a popup window (real popup, not a jquery kind of popup), closing the popup after they login and storing their tokens in a PHP $_SESSION. Question is, I have quite a lot of stuff going on with jQuery and I'd like to let them switch between commenting as a visitor to the site to commenting on Flickr/YouTube after they login without refresh.
Basically, I'd need a way to detect when the pop-up closes so I could then make a request to a PHP file which would tell me if the user has a token saved in the $_SESSION or not and hide the name and email boxes from the comment form as they would only need the input box.
Another way would be to trigger a setInterval() when they open the popup and check for the $_SESSION every 2/3 seconds for example, but I don't think that's the best way to go. Ideally I'd want something that works as soon as the user closes the popup.
More details:
I'm using http://swip.codylindley.com/popupWindowDemo.html to display the pop-ups
The callback script for both functions does a self.close() after storing the token in a $_SESSION
Users can be logged in with both Flickr and Youtube (but I don't think this matters anymore).
Difference between commenting as a visitor and Flickr/Youtube user is that you have three fields (name, email, message) as a visitor and just one otherwise (message)
I do a check when page loads, so if the user refreshes the page at this point, everything is ok, but I would like it if he didn't have to do that, or if at least it would refresh automatically.
Lastly, I'm good to go with other options, as long as the user doesn't have to leave the page, refresh himself to swap between visitor and logged in user. Using jQuery in the page so if it's a jQuery based solution, even better.
Sorry for the long post, couldn't find a way to make it shorter.
Thank you for the help guys!
EDIT
setInterval() with a function that calls a PHP script to check for the $_SESSION variable worked like a charm, not at all as bad on performance or user experience as I expected. Still, if anyone can think of a better solution I'm ready to accept it.
Thanks!
You could place in the pop-window HTML code:
<body onunload="window.opener.location.href = 'http://check.session.com/path/to/file.php'">