Maintaining State Between HTML page and PHP Server Page - php

I am designing a simple drag and drop quiz. We are limiting the number of attempts to get a correct answer to two for each box/answer. However, I'd like to keep the functionality and state of the quiz separate from the display/view.
Currently, as the user attempts to get a correct answer by dropping an answer box on top of a question box, an ajax call is made to a PHP page which returns a 'true' or 'false' value.
We have been evaluating if we want to use Session variables on the PHP page, cookies, or something even more simple to track how many attempts each box has consumed. It would be preferable (for good form's sake) to somehow maintain the state of this data on the server - so the client has no idea what is going on. Session variables seemed to make sense to me - as the user continues to make attempts with different question/answer combos, the server tracks the number of tries and returns (in the ajax response) the result of a user's question (right/wrong, and how many tries that answer has remaining, if any) but I'm wondering if there's a better solution. Any input?

Session seems like a good fit to me. Cookies can be tampered with so I would avoid that if you need the error count to be accurate.

Sessions is probably your best bet. Cookies could be used as well, or if you can guarantee availability of HTML5 localStorage in the browser, you could use that as well.

Unfortunately to keep the functionality separate, there is not. You can use a session variable, or database storage paired with a session id stored in a cookie.

Store current user state into session (temporary storage) and track what he have answered what not etc. at the last step store data into database, or file (permanent storage). Session is individual for every user. Users can't alter your site sessions.
Session usage

Related

How to save $_SESSION variable when it times out on the server

I'm doing research on internet behavior. The participants of my study are asked to fill in a questionnaire.
What they don't know is that this questionnaire consists of an infinite series of forms:
whenever they submit one form, they are presented with another one. From their perspective, the questionnaire never ends. It is filled from an array containing thousands of random questions from old studies.
I want to test, how long different users keep going.
I have two options:
Save each form to the database, when it is submitted. Each successive form UPDATEs the same data record with the current page count. This is easy, and I know how to do it.
No data is saved while the user performs the task. The current page count is saved from the SESSION, when the user abandons the task, i.e. when he closes the browser window.
How do I do this? How can I tell PHP to save a $_SESSION variable, when the user closes the browser? Is this even possible in a reliable way, i.e. the solution does not rely on functionality that is not available in all browsers, such as onbeforeunload (which does not work in Opera)?
$_SESSION is profoundly unfit for the task you want to perform. It is designed (and works well enough) as a vehicle to introduce state into an application relying on the stateless HTTP protocol, not to do something on the absence of further HTTP requests.
When relying on a server-sided mechanism, one of the main points to consider is, that session cleanup can happen concurrently, which is not a problem for dumb destruction of a session, but will hand you problems if you want to do something else.
Relying on client-sided code is much worse: What if the user doesn't close the browser, but it crashes? Or the user is on mobile and drives into a tunnel?
My recommendation would be, to understand, that your problem at hand is not one of session keeping, but one of analytics. This would argue heavily into inserting one row per page into a database:
Do your analytics a posteriori: Are you sure, you already know all questions, you want to ask? Only raw data is able to allow you to change or append to your research problem.
Including a timestamp in the rows will allow you to ask for correlation between response time and total time ... was the user doing your survey just as a side-distraction or was he concentrated on it?
Basically you create a specialized log, that can be analyzed by lots of tools - it being in the DB making it easier to query it.
What I do now is save the current state of the session into a database with session_encode() after each form is sent. Before I show any user any page, I check if there is a session with isset($_SESSION['whatever']). If there is none, I check in the database, if a session was stored for this user (they are identified through a login, all this takes place on a site that requires registration). If a session was stored, I drag it from the database and resore it with session_decode(). If there is none, I create a new one. Now, when the browser was closed, the user gets returned to the last page with all variables (of all previous pages) prefilled, including current error messages ("Please choose ..."), if there where any.

Storing data into session and storing to database upon "major" action

I know there are hundreds of these questions but what I am asking however is slightly different.
When the user logs in I would like to get all their data from each table in a database and store it in a session variable (obviously not sensative data such as encrypted password/salts etc basically data that would be useless or have no value to a hacker!!), and whilst the user uses the website the relevant data stored in the session will be used as opposed to accessing the database everytime. Moreover when the data is changed or added this will be written or added to the session file, and upon a major action such as "saving" or "loggin out" the new/changed data will be written to the database.
The reason I wish to do this is simply for efficieny, I want my application to not only be fast but less resource consuming. I am no expert on either which may explain why my idea makes no differnece or is more resource intensive.
If there is an alternative to my solution please let me know or if there is something to improve on my solution I will be glad to hear it.
Thank you.
My application is using PHP and mysql.
If any of these don't apply to your app, then please ignore. In general, I'm against using sessions as caches (especially if anything in the session is going to be written back to the DB). Here's why.
Editing the session requires a request from the user. Editing a php session outside of the request-response cycle is very difficult. So if a user Alice makes a change which affects Bob, you have no way to dirty Bob's cache
You can't assume users will log out. They may just leave so you have to deal with saving info if the session times out. Again, this is difficult outside of the request-response cycle and you can't exactly leave session files lying around forever until the user comes back (php will gc them by default)
If the user requires authentication, you're storing private information in the session. Some users may not be happy about that. More importantly, a hacker could imploy that private information to conduct a social engineering attack against the end-user.
Mallory (a hacker) might not be able to use the information you put in the session, but she can poison it (ie. cache poisoning), thereby causing all sorts of problems when you write your cache to your permanent storage. Sessions are easier to poison then something like redis or memcache.
TL;DR Lots of considerations when using a session cache. My recommendation is redis/memcache.
You can also go for local-storage in HTML5, check The Guide and THE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS
Local Storage in HTML5 actually uses your browsers sqlite database that works as cookies but it stores data permanently to your browser
unless someone by force remove the data from the browser finding the data files
Or if someone remove/uninstall browser completely,
or if someone uses the application in private/incognito mode of the browser,
What you need to do
Copy the schema for required tables and for required columns and update data at a regular interval
you dont have to worry about user's state, you only have to update the complete data from the localStorage to mysql Server (and from the mysql server to localStorage if required) every time user backs to your application and keep updating the data at regular interval
Now this is turning out to be more of localStorage but I think this is one of the best solution available for me.
redis is a good solution if it is available for you (sometimes developers can't install external modules for some reason) what I would do is either go with your Session approach but with encoded/encrypted and serialized data. Or, which I really prefer is to use HTML5 data properties such as:
<someElement id="someId" data-x="HiX" data-y="Hi-Y" />
which BTW works fine with all browsers even with IE6 but with some tweaks, specially if your application uses jquery and ajax. this would really be handful.
You need to use Memcache for this kind of work. To solve the problem of keeping the updated data everywhere you can create functions for fetching the data, for example when the user logs in you, authenticate the user and after that insert all the user data into the memcache with unique keys like :-
USER_ID_USERNAME for user's username
USER_ID_NAME for user's name
etc...
Now create some more functions to fetch all this data whenever you need it. For ex
function getName($user_id){
if(Memcache::get($user_id."_name"){
return Memcache::get($user_id."_name");
} else {
//Call another function which will fetch the data from the DB and store it in the cache
}
}
You will need to create functions to fetch every kind of data related to the user. And as you said you want to update this data on some major event. You can try updating the data using CRON or something like that, because as tazer84 mentioned users may never log out.
I also use what the OP described to avoid calls to db. For example, when a user logs-in, i have a "welcome-tip" on their control panel like
Welcome, <USERS NAME HERE>
If i stored only his user_id on $_SESSION then in every pageview i would have to retrieve his information from the database just to have his name available, like SELECT user_name FROM users WHERE user_id = $_SESSION['user']['user_id'] So to avoid this, i store some of his information in $_SESSION.
Be careful! When there is a change on data, you must modify the data in db and if successfull also modify the $_SESSION.
In my example, when a user edits his name (which i also store in $_SESSION so i can use it to welcome-tip), i do something like:
If (UpdateCurrentUserData($new_data)) // this is the function that modifies the db
{
$_SESSION['user']['user_name']=$new_data['user_name']; // update session also!
}
Attention to:
session.gc_maxlifetime in your php.ini
This value says how much time the $_SESSION is protected from being erased by the garbage collector (the file that exists on your disk in which the $_SESSION data are stored)
If you set this very low, users may start getting logged-out unexpectedly if they are idle more than this amount of time because garbage collector will delete their session file too quickly
if you set this very high, you may end up with lots of unused $_SESSION files of users that have left your website a long time ago.
also i must add that gc_maxlifetime works together with session.gc_probability where in general you need lower probability for high-traffic websites and bigger probability for lower traffic since for each pageview there is a session.gc_probability that garbage collector will be activated.
A nice more detailed explanation here http://www.appnovation.com/blog/session-garbage-collection-php
I know this sounds stupid but ....
If ur data is not sensitive the best way to make it accessible faster is to store it in hidden variables inside the forms itself. You can save comma separated or values in an array.

Is passing session data from one PHP page to another efficient?

I was wondering if using a SESSION variable to pass data from one PHP page to another is efficient. I ask this because I thought that SESSIONS were only used to keep the user logged in to a website, and as an alternative to cookies. Would it not be better to pass data (non-sensitive) from one page to another via a URI such as members.php?name=Joe&age=28?
A PHP session writes a cookie to your browser and then stores the data associated with that session on disk; its about as expensive as an include() to read it back in on the next page load, which is to say completely trivial.
Additionally, the user can't change session data unless you create a mechanism which allows them to; they can mess with the query string easily.
Short answer: Yes, its efficient.
Sessions are useful for lots of things, not just login information. They're great for holding status messages during a POST/redirect/GET cycle or anything else that keeps track of the state of the user's session (hence the name) - but only the current session, not long-term permanent configuration options.
As far as efficiency goes, you need to remember that anything in the session needs to be serialized & unserialized on every page load. Storing a name and age wouldn't add much. Adding a megabyte of image upload would probably be bad.
More important than the efficiency consideration is to remember that session data is only temporarily persistent. If you want to always know that Joe is 28, it should go in the database. If it's only useful on a single page load, it should probably stay in the URL or be POSTed. If you're interested in remembering it for a few minutes, the session might be the place to put it.
Depends on what you're doing. If that page requires that information to function properly and is not behind a login then passing in a query string is the way to go (e.g. search results, product pages). If it is behind a login then using a session would allow you to keep your URLs clean and also make it difficult for users to abuse the page (e.g. swap out data in the query string).
Yes, you can store data and message in SESSION and it is accessible from any page. But remember, SESSION uses browser support to store data. They can be deleted manually by the user

Alternative to using $_SESSION variables to solve multiple tab issue

I started writing a web application that stores certain user information in the $_SESSION variable. Usual stuff - user_id, username etc.
I then started using the variables to store certain navigation information. For instance, $_SESSION['organisation_id'] so that wherever the user is in the application, I can easily add 'organisation_id' to any table without having to parse 'organisation_id' across every page request (eg. index.php?organisation_id=456&var2=6 or anotherpage.php?organisation_id=456& etc)
All hunky dory until a user opens a new tab and starts navigating to another organisation so hence creating a new $_SESSION['organisation_id'] value and creating an epic fail on the original tab.
The only solution I can think of is to go back to putting organisation_id into every form and navigation element within the application but yeesh, I'm thinking there must be a more elegant solution.
Normally, I find everything I need on StackOverflow but the answer to this question still eludes me!
"The only solution i can think of is to go back to putting organisation_id into every form and navigation element within the application but yeesh, i'm thinking there must be a more elegant solution."
No there isn't.
Maybe you can check if $_SESSION['organisation_id'] exist, and if so you can write new variable in session with different name, and so one.
Currently there is no way to solve the problem. But to avoid a similar task in the future, I would suggest split up all your files into different includes.
So even if you have to add a couple of variables to the entire site, you could modify 1 file and get it done than doing the whole thing again.
I think this is a logic problem. The session represents a state for the user. This is because HTTP is a stateless protocol in it's essence (it don't know who is who, just undersdants requests and responses).
So the organization_id is a state. If a user can login to just one organization, you just store this in the session var like you did and use it. If the user logs out and in again with another organization_id, it makes sense that only the last one remain available.
If your application has to support multiple organization_id's, you should reflect that logic in your session handling, saving an array of organization ids for instance (instead of just one). But then you have to change your application to allow the user to navigate from organization to organization, etc. There's no point in letting the user be in two organizations at once if the screen just shows one of them.
you can store the value into session during onblur of that username, etc and you can get it before you clicking the next tab
(i.e) using Jquery/Javascript u can get that value of username, etc while onblur and store it in session.
You can resolve this by simply moving the data you currently put into the $_SESSION array into a sub-array within $_SESSION, so that you can store multiple sets of data at once in the session.
It would end up looking a bit like this:
$_SESSION[organisations] = array(
'456' => array('organisationID'=>456, 'otherdata'=>'blah'),
'678' => array('organisationID'=>678, 'otherdata'=>'blah'),
...etc...
);
This will allow you to keep the data for multiple orgs in the session data at once, so you don't have to load all the data every time.
But yes, you will need to send the relevant organisationID with every request, so that your code knows which element of the session data to work with. You can't really work around that. Every request will need tell PHP which orgID to work with.
The down-sides here are that by storing all that data in the session, you're using a lot more memory for your session data, so if there's a chance that the user will browse a lot of organisations during a session, I would advise limiting the size of $_SESSION by dropping data that hasn't been used for a while.
The other down-side is that if this is a multi-user system, storing the data in session means that it will be unaware of any updates made by other users. If you were to load the data fresh from the database on every request, yes it would create more work for the DB, but it would ensure that the data given to the user was always up-to-date.

Am doing online Quiz type of script in PHP. It is better to use cookies or sessions

Am doing online Quiz type of script in PHP. User needs to attend 50 Question in 45 minutes.
After that time it should close the page or Submit the answer to the next page.
It is better to use cookies or sessions. How can i do that.
Am novice in session concept so can u suggest the suitable code.
Awaiting the earliest reply
I assume, as this is a quizz, you'll count point, record ranks, etc. So your users will eventually try to cheat.
Therefor, I would recommend sessions which are only server-side.$_SESSION is an array, like $_GET and $_POST, unique to every user using your website. You can put and retrieve anything when you want.
The only thing client side is a special cookie, called PHPSESSID, which is your visitor's id, used by PHP to retrieve his $_SESSIONarray.
Only things you have to do is to begin every page with session_start(); , before any instructions (except if you use buffering like ob_start())
The main difference between cookies and sessions is where the data is stored.
With cookies, you send the data to the browser, and the browser keeps sending it back to you with every request thereafter.
With sessions, you're storing the data in memory, and then just setting one cookie that has an ID to identify the chunk of space in the server's memory where the data is stored.
The crucial difference is that when the data is stored in cookies:
it can be edited by the user
it can be seen on the network as requests are made
it adds to the weight of each request in additional bandwidth required
it takes up less server memory
When data is stored in the session:
it can't be accessed by the user without going through you
it's not sent back and forth with each request (only the session ID cookie is)
but it takes up memory on the server
it can cause issues on larger sites when needing to move to multiple web servers
I would say it depends on scale. For a lot of questions, those cookies will get heavy and make each request very large. If you quiz is running in an environment that is spread across multiple front-end web servers, sessions might be out of the question.
I suspect the deciding factor is going to be the integrity of the quiz though. If it's crucial that the user can't change the data (such as previous answers, a running score or a timestamp for the start of the quiz) then you'll need to store the data out of their reach, which means using sessions.

Categories