The term Session in web development refers to a general method of storing semi-permanent data, such as user logins, user interactions, ecommerce shopping carts, and many other examples. PHP has a system called $_SESSION, which is exceptionally simple to use, but has same major draw backs, including security issues, and intermittent support across server environments. A few months ago, Eric Mann introduced WP_Session; a new library that provides a session data storage system that has the simplicity of $_SESSIONs but without many of the drawbacks.
WP_Session allows you to store data in exactly the same way as you would with $_SESSION. For example, when using $_SESSION, you might do something like this:
1 2 3 4 5 6 7 8 9 10 | $_SESSION['cart_items'] = array( array( 'item_id' => 43, 'item_name' => 'My Product Name' ), array( 'item_id' => 22, 'item_name' => 'My Second Product Name' ) ); |
or
1 | $cart_items = ! empty( $_SESSION['cart_items'] ) ? $_SESSION['cart_items'] : false; |
With WP_Session, you can perform the exact same type of actions with a nearly identical syntax:
1 2 3 4 5 6 7 8 9 10 11 12 | global $wp_session; $wp_session['cart_items'] = array( array( 'item_id' => 43, 'item_name' => 'My Product Name' ), array( 'item_id' => 22, 'item_name' => 'My Second Product Name' ) ); |
and
1 | $cart_items = ! empty( $wp_session['cart_items'] ) ? $wp_session['cart_items'] : false; |
Eric has made the implementation of WP_Session extremely simple with his WP_Session Manager plugin, available for free from WordPress.org.
I recently used Eric’s WP_Session class in Easy Digital Downloads with excellent results. Because I wanted to integrate it directly into my plugin, without relying on the installation of a second plugin, I included the WP_Session library as part of EDD and then wrote a wrapper class to handle the setting and retrieval of session data. You can see my wrapper class on Github.
When I want to store some session data in Easy Digital Downloads, such as when a customer adds an item to the shopping cart, I simply do this:
1 2 3 4 5 6 7 8 9 10 11 12 | $cart = array( array( 'item_id' => 43, 'item_name' => 'My Product Name' ), array( 'item_id' => 22, 'item_name' => 'My Second Product Name' ) ); EDD()->session->set( 'edd_cart', $cart ); |
And when I want to retrieve the session data:
1 | EDD()->session->get( 'edd_cart' ); |
When Easy Digital Downloads was first written, it relied on $_SESSION for cart storage, as well as several other pieces of session data necessary for the plugin to operate. This resulted in a rather large number of support tickets from users that experienced problems due to the lack fo support for $_SESSION on their servers. By switching to WP_Session, we reduced the number of tickets related to session data problems by probably 90% or more.
Have you used WP_Session? What was your experience? I am personally a big advocate for it and would strongly encourage you to give it a test.
To read more about why Eric created WP_Session, and the types of problems it solves, read his original proposal.
awesome mate , this will come in handy 😉
Nice, thanks for the heads up, Pippin
what’s the advantage over, say, HTML5 session storage?
A couple, actually.
First, storing data locally means it’s available in the browser – i.e. to any browser plugins running on the page and potentially to the user (who may or may not have malicious intent). Keeping data on the server is more secure.
Second, not everyone visiting your site will have browser storage. There are polyfills for this, but not every fallback is created equal and some browsers just have low data limits.
apparently, local storage is not recommended anymore
I gave WP_Session a try, and while the code looks beautiful, I decided against using it for my custom fields plugin.
1. expiration time – there can only be 1 expiration time (even with the wp_session_expiration filter). For example, if EDD needs a 30 minute expiration, and my plugin needs 2+ hours, I don’t think it can be both.
2. PHP notices prevent cookies from being written. Sessions depend on cookies. Cookies are set in the HTTP-Header, so they’ll only get written if no output has yet been generated. If other plugins trigger errors, then technically the output *has* been started, and no cookie will be written.
3. Session data gets stored in wp_options. This isn’t necessarily a bad thing, but the wp_options table will quickly get filled with thousands of rows of session data. The session cleanup process is also considerably less efficient than a devoted “wp_sessions” table (WP_Session wisely performs cleanup via cron).
1. That’s not actually true anymore: https://github.com/ericmann/wp-session-manager/blob/master/class-wp-session.php#L114
2. That is a definitely possibility, but considering WordPress relies on cookies, I personally do not have any problem with this. In my mind, this is a much better limitation than relying on servers that don’t support $_SESSION.
3. Not thousands because the rows are automatically cleaned out via a cron job, but you’re right that a custom table could provide better performance, but I think the difference is almost negligible.
1. Expiration time is filterable in the plugin (see Pippin’s link).
2. This would affect any cookies sent by WordPress – i.e. authentication cookies or the standard PHPSESSION cookie used when $_SESSION is invoked directly. If your site is throwing notices and blocking cookies, then you can’t use regular sessions (or even properly log in to WordPress) either.
3. A custom table used by a plugin/library is … not going to happen. The overall goal here is to eventually make WP_Session part of WP itself and make it available for third party devs to use. If/when it’s available for core we can investigate adding a separate table.
Hey guys –
1. Even with the filter, my understanding is that 2 plugins can’t have 2 separate expirations. Is that not the case? My plugin could set the expiration to 4 hours, but what if EDD still needs a 24 minute expiration?
2. True, I’m not trying to bash WP_Session, just pointing out that these kind of issues happen with cookies regardless. I ended up going the token route (store session data in DB, and a unique form token on each pageload). Even though it’s not ideal, it’s the best way I could find that got around the dependence on cookies.
1. Two expirations? No. But even with traditional sessions you can’t specify multiple expiration windows. And remember, expirations aren’t set to be hard – it’s an after inactivity expiration. In other words, if you load the page, then leave, then reload the page within 24 mins your session is still good. Also, you automatically reset the expiration of the session during that reload.
But if you absolutely need your sessions to live for longer than that, just filter the default with a lower priority – this will make all sessions live for longer. But if you need to go down this route, I’d argue that sessions aren’t the right tool for the job. Do you actually have people fill out a form/populate a shopping cart, leave, and come back 4 hours later expecting things to still be filled in?
2. Tokens work, but usually only for forms since you need to resubmit the tokens with each page transition (cookies are submitted automatically).
Why not use table-based PHP session handler instead of reinventing the session wheel?
It’s much simpler to code and runs more efficiently and far faster. More importantly, it maintains compatibility with a growing number of plugins who use the native PHP $_SESSION.
In addition, you eliminate the need for CRON as PHP natively handles garbage collection for sessions.
Also remember that a WP_SESSION plugin that relies on a cookie is inherently *not* safer than a native PHP session.
At the moment, I am only aware of WpEngine.com not enabling PHP sessions. As a rule, though, I would shy away from any hosting company who didn’t offer a full version of PHP.
There are a lot more hosts than just WPEngine that disable $_SESSION. Having used $_SESSION in Easy Digital Downloads for nearly a year, I can tell you first hand how many support tickets were a result of hosts having it disabled.
My membership plugin is out there, scattered around some 5000-6000 sites/hosts and, of those, so far only WpEngine.com disable native PHP sessions. In order to test in various environments, I have hosting accounts with most mainstream hosting providers (GoDaddy, DreamHost, BlueHost, HostGator, 1&1, Amazon EC2) and unless people are using off-the-wall outfits, you’ll find that native sessions are generally available.
All the same, if a hosting company disables native PHP sessions, I would look for another provider. As they say: Don’t walk, run!, as you’ll have no guarantees that they haven’t taken other shortcuts.
The security aspects cited by WpEngine.com are irrelevant within a WordPress site which is cookie-driven anyways. WP_SESSION is in the same boat: it neither fixes any security gaps nor creates any new ones.
I have to disagree with you on selecting a new host if PHP $_SESSIONs are disabled. Do a bit of research and you’ll find countless articles citing problems with using $_SESSIONs due to host configs. Yes they are usually enabled, but they are disabled frequently enough that the idea of not using them should at least be considered, even if not acted upon.
I’m only relating my own experience going back to 2005. If yours is different, I can accept that.
However, in my opinion, a hosting provider who is not able to provide a stable environment that includes PHP sessions should not be considered.
As you pointed out earlier, there are a lot of applications (i.e. Magento and other shopping carts) that use/require PHP sessions. Unless changing hosts is someone’s hobby, one should plan for the future and be open to anything that might come along.
Simply put, sessions are an integral part of PHP. Using a third-party product that doesn’t solve any of the potential issues inherent to PHP sessions is not really an alternative – without detracting from the fine coding that Eric Mann has put together.
I built WP_Session to address some specific issues:
Enabling session support in environments where sessions are disabled or incorrectly configured – rather than providing sysadmin instructions to end users who just want their site to “work.”
Getting past multiple server issues where sessions are stored in the filesystem on the physical machine
Providing a reliable API for WordPress that future devs can use without needing to guess about how or whether sessions are set up on the target server.
So I’m curious what other “potential issues inherent to PHP sessions” you’d like to see addressed.
By “potential issues”, I am referring to the potential security issues that can happen on shared hosting, public computers, etc.
These are well documented and probably don’t need to be addressed in detail here.
Session data stored in the database is just as secure as … anything else you have stored in the database. Sessions (using either WP_Session or $_SESSION) are not more or less secure than WordPress itself – if WordPress can read/write the data, then anyone with access to WordPress can read/write the data.
As for shared machine issues … identifying users based on just the physical machine they’re on (versus requiring a log in) is an issue with anonymous interaction, not sessions themselves.
Yes, it’s what I’ve been saying.
Hi i have a problem in retiving values in wordpress. i am working on core php but when i converted in to the wordpress i am not able to get values form databse.i change syntax according to the wordpress. my values store in database but bot able to see the value on other page.
Thanx
Sanket
Please post this type of question to the WordPress.org support forums. It is not relevant to this tutorial.
Hey Pippin and commenters, I posted a question about storing session data in the wp_options table over on Eric’s blog, would be great to get your input on it…
http://eamann.com/tech/introducing-wp_session/#comment-1264
I would second what Eric said.
Thanks buddy, i was searching for tutorials to deal with WP session. This is really very much helpful.
using this plugin, I deactivated it to see if it as causing issues with another plugin and it has brought down my entire site, including back end, and i am desperately trying to get it back up.
Using WP Session has brought your site down?
@Pippin in a custom gateway for EDD I am using EDD()->session->set(); to store a data in a session before a user submits the checkout form and using EDD()->session->get(); to get the data that I stored initially in a custom page.
Is this bad and will like to know how to unset the session once a payment has been processed and marked as successful.
What kind of data are you storing?
Don’t worry about unsetting the session data, EDD will take care of that for you.
I want to store some data that I want to pass to a page that process my payment.
My payment gateway uses a form to process payment.
So once a user click on the proceed button on the checkout page, I will save the data in the session and access it in my custom page.
Hope this is cool.
As long as it is not credit card info or anything sensitive like that, it should be fine.
Deleting native $_SESSION, tampering with the htaccess file, what’s next? WordPress will overwrite my HTML codes too?
Seriously, these “security protection” stuffs only protect the site from noob coders and only halting real developers’ work.
Please give me back the 2 hours of my life, which I spent debugging why $_SESSION was not working as expected.
Looking forward for more of these lovely programming constrains from wordpress.
WordPress has nothing to do with whether $_SESSION variable are enabled, that’s entirely dependent upon your webhost.
Please, I need a detailed help/guide on how to use this wp session in a shopping cart in which I want the checkout button to send data of the session to a email.
Hi. Sorry for my ignorance, but how can I install and use class-edd-session?
Yours,
Francisco
EDD_Session is specific to Easy Digital Downloads. You will want to look at the install guide for WP_Session: https://wordpress.org/plugins/wp-session-manager/
Haa ok, thanks!
I cannot get it to work. I have a php program that is external to WordPress; in it I did this:
global $wp_session;
$wp_session[‘basic_plan’] = $basic;
$wp_session[‘recom_plan’] = $recommend;
$wp_session[‘gold_plan’] = $gold;
$wp_session[‘platinum_plan’] = $platinum;
$wp_session[‘aeration_cost’] = $aeration;
In subsequent WordPress pages, the values are zero. I know they are NOT zero in this program because I have echoed them; they are there.
Any ideas
Is your PHP script loading WordPress? It can only work if WordPress is loaded.
It does this before it uses $wp_session
require( ‘wp-load.php’ );
Is the path to wp-load.php correct?
wp-load is in the same folder (directory) as the script.
Does your site have any caching plugins active?
It would be cool if there was something like a package manager for WordPress plugins where you could have WP_Session be a dependency for the plugin you were creating. That way you could use WP_Session without having to embed it in your plugin and without having to have the end user install additional stuff. Do you know if anything like that is being worked on?
At one point there was a discussion of trying to get something put into WordPress core, but I don’t believe it ever went very far.
WooCommerce has a new sessions handler in v2.5. WooCommerce uses this technique that you describe above but instead of WP options table I believe they put the data in a table called wp_woocommerce_sessions. I’m curious what benefit this gives them and if this benefit/functionality can be expanded before a cart is made. I’m looking to capture pause-time data of videos on my shop and individual product pages. The pause time determines which product to add to cart.
Really enjoying your tutorials, learning lots!
Hi Pippin,
Please excuse my ignorance, but can you please explain the “EDD()” in “EDD()->session->set( ‘edd_cart’, $cart );”? I can’t figure out how or where this is defined. I don’t see anything in your class-edd-session.php
I’m trying to get your wrapper class to work in another plugin.
No matter what I change ‘EDD()’ to, I get an ‘undefined function’ error.
Thanks.
Hi Pippin, this plugin sounds perfect for what I need to do, but it hasn’t been updated for two years. Do you have any thoughts on whether it’s likely to have aged well? Anything you’ve needed to modify in your own code that should also be updated in the plugin?
Thanks so much!
Donna
We still use almost the exact same version in Easy Digital Downloads without any issues.
hi, i add your method and all classes but i dont where i do mistake i got this error.sorry for my english
Fatal error: Call to undefined function EDD()
global $wp_session;
$wp_session = WP_Session::get_instance();
$edd = new EDD_Session();
$more =
array(
‘item_name’ => ‘dfgsdf’,
‘item_asin’ => $asin,
‘item_image’ => $image,
‘item_qty’ => $qty,
‘item_price’ => $price
);
i tried both this is what i thought.
echo $edd->set( ‘edd_cart’, $more );
this is your tutorial.
EDD()->session->set( ‘edd_cart’, $more );
Read more about session
http://www.webtechsource.com/session-in-php/
Just a heads up, it looks like Eric Mann’s original WP_Session proposal has moved to https://ttmm.io/tech/wp_session-a-proposal/ (with the original link above no longer working).
Hello Pippin, thanks for the awesome blog post, and in fact I would like to know something about cookies in WordPress, like how to set it up correctly, use it correctly, some cookies security explanation and many more. Can you please post a new blog about cookies in wordpress. Thanks!
Hi Pippin,
is this post still up to date? I think the information out there (in the big www) is very confusing how or when to use sessions or cookies (in wordpress) and how it brakes sites and prevents caching.