On an e-commerce site with no username/login to persist cart data, would it be better to use the PHP $_SESSION variable or a browser cookie to persist items in the shopping cart
As pointed out by Xeoncross, it is very important to store any possible information for analysis. So one should not entirely rely on sessions and cookies.
A possible approach is-
Use sessions if not logged in
If the user is not logged in, you can store and retrieve the cart items and wishlist items from session using $_SESSION
in PHP
Use database when logged in
If the user is logged in then you can consider one of the two options -
When user logs in
When the user logs in, get all the cart items and wishlist items from the session and store it in the database.
This will make the data persistent even if the user logs out or changes the machine but till the user has not logged in, there is no way to store the information permanently so it will not be persistent.
Getting required data
Whenever you are trying to access cart or wishlist do the following check -
I would use a session. If a user has cookies disabled then the session won't be able to start as the session ID is stored on the user's machine in a cookie.
There are some settings you may want to look at in order to attempt to keep the sessions for longer.
Prevent the session cookie from being deleted when the user closes their browser by running session_set_cookie_params() with the lifetime
parameter set. This function needs to run before session_start()
You may also want to extend how often sessions are cleared from the server by modifying the session garbage collection settings session.gc_probability, session.gc_divisor, session.gc_maxlifetime either in php.ini or using ini_set()
If you have other websites running on the server and you modify the above garbage collection settings you will need them set in php.ini so they apply to all websites, or if you are using ini_set()
then you might also look at saving these sessions to a different directory than other websites by modifying session_save_path(). Again this is run before session_start()
. This will prevent the garbage collection of other websites clearing up your extended sessions for one particular site.
I would also recommend setting the following session settings in php.ini session.entropy_file = /dev/urandom, session.entropy_length = 256, session.hash_function = sha512
. That should give you a cryptographically strong session ID with an extremely tiny chance of collisions.
And make sure you have an SSL cert on your site to prevent man in the middle attacks against your session ID.
Obviously a user could still decide to manually clear all their cookies which will take the session ID cookie with it but that's a risk I'd be prepared to take. If I was halfway through a shopping cart system and hadn't checked out, I wouldn't go and clear my cookies. I still think sessions are better than just using plain cookies.
The data is secure enough so long as you are the only website that has access to your sessions directory and your session ID is strong. And by extending the server's session storage time your data can persist on the server.
There are further measures you could employ to make your sessions even stronger. Regenerate your session ID every 20 minutes, copying the data over. Also record session IDs against IP addresses in a database and check to see if a particular IP address attempts to send more than X number of session IDs in a given time to prevent someone trying to brute force a session ID.
You could also store the data in a database linked by the session ID, instead of in a session file on the server. However this is still reliant on a session ID which is stored in a cookie and could disappear at any time. The only way to truly be sure that a user doesn't lose their cart is by having them login first and storing in a database.
Some points to help:
Cookies:
Session:
I would personally go with sessions, since I'm assuming to be a small/meddium auddience page. If it grows, you would be better with a simple DB structure to store this data, with a maintenance plan to get ridge of unnecessary data (eg: clients that choose some products but don't do the checkout).
I would store it in a SESSION. My wish list is rather long, and I am afraid that it will not fit in the 4K storage that a COOKIE may occupy. It forces you set the session time out to a longer period.
note: there are some countries (like the Netherlands, where I am) that have very strict policies about cookies, and you may be forced by legislation to use Sessions.
No large sites would dare store a user's cart in a session or cookie - that data is just to valuable.
What customers are buying, when they select items, how many they purchase, why they don't finish the checkout, etc.. are all very, very important to your business.
Use a database table to store this information and then link it to the user's session. That way you don't lose the information and you can go back and build statistics based on users carts or solve problems with your checkout process.
Log everything you can.
Below is a simplified example of how this might look at the database level.
user {
id
email
}
product {
id
name
price
}
cart {
id
product_id
user_id
quantity
timestamp (when was it created?)
expired (is this cart still active?)
}
You might also want to split the cart table out into more tables so you can track revisions to the cart.
Normal PHP Sessions consist of two parts
Therefore, it's not $_SESSION
vs $_COOKIE
- it's $_SESSION
+ $_COOKIE
= "session". However, there are ways you can modify this by using a single encrypted cookie which contains the data (and therefore you don't need an identifier to find the data). Another common approach is to store the data in memcached or a database instead of the filesystem so that multiple servers can access it.
What @Travesty3 is saying is that you can have two cookies - one for the session, and another that is either a "keep me logged in" cookie (which exists longer than the session cookie), or a copy of the data inside separate cookie.
You might consider using both.
The drawback with $_SESSION
is that the session is cleared when the browser is closed.
Use sessions, but attempt to populate the $_SESSION data from a cookie, if it's available.