When moving your site to WP Engine, it’s important to understand how cookies and PHP Sessions are handled. In this article we’ll explain what cookies and PHP Sessions are, how they interact with page caching, and the performance implications of using them.
What are Cookies?
The term “cookie” refers to contextual bits of data your web browser stores. For example, a cookie could be used to display different information on a website for different users, or to gather data about the browsing activity of users on your site.
Cookies are assigned to individual users on your website, which means they are not intended to span multiple user sessions. The bits of data stored or sent should have the ability to return a unique value and apply a unique set of rules. For example, if you want your website to show a specific popup for users who are already subscribers, compared to users who are not already subscribers, a cookie could help accomplish this.
Conflicts with Cookies
When using page caching, the typical flow for the first page request looks something like this:
But on the second view, many of these steps are saved because of caching:
This process works well to help ensure your page is returned quickly. When a page is cached, the entire HTML is already pre-populated and formed before the user even requests the page.
The conflict here is that cookies which exist to perform a specific action (i.e. show a different sidebar, or different page altogether) do not expect the page to be fully formed before they request it. When present, these cookies expect to interact with PHP in order to perform their unique action. But as you can see in the example above, cached pages do not get processed and built by PHP as uncached ones do.
As a result, your cookie may only work as expected when logged in to the WordPress Admin Dashboard. This is because logged-in user sessions specifically bypass the page cache layer, and will be processed by PHP every time.
Whenever possible, we recommend populating all the available options for the action you wish to take with HTML or PHP. Then, you can use JavaScript to select which option to load (based on the presence of the cookie). In this way, the fully-formed page served by cache will still fit all scenarios, since browser-side JavaScript will determine which of the available options show. Below is an example of some very simple conditional HTML. This code says to show one sidebar image when a preferred user visits, and another for those who need to sign up. Then, my JavaScript reads the $_COOKIE header to determine which sidebar image to show.
What are my options?
So what happens if you need to perform a cookie-based action for users on your site? If you try to use PHP to read cookies, it will likely only display an empty cookie array. And while it’s not ideal, we understand that sometimes this might be a necessity for sites. Not to worry: page caching does not automatically mean that you can’t use PHP to read cookies!
There are two different ways to approach the issue of reading cookies using PHP:
- Use admin-ajax calls
- Contact Support to request a cache exclusion
Use Admin-Ajax Calls
In this method, the JavaScript triggers a POST request to admin-ajax.php, which PHP is then able to receive and, if needed, perform different actions. This scenario should only be used if your page is not making any other admin-ajax requests to begin with. Sending multiple requests to admin-ajax.php is not ideal, and the benefits of only loading specific parts of the page uncached is negated by the number of uncached requests being sent overall.
In this code snippet you can find an example of the exact scenario above, only using an admin-ajax.php call instead: https://gist.github.com/octalmage/2df40777a983b9ba92c6fd351ee615b3
Exclude Pages from Cache when Cookie is Present
If your page already uses admin-ajax.php requests, the better option is likely to exclude the page from cache conditionally. This way your pages can still be cached, except for when your specific cookie is present. With this method, the entire page is built fresh in PHP for your users when the cookie is present. Remember: using uncached pages will not scale well with extra traffic! But, this method is certainly preferable to sending multiple admin-ajax.php requests from the same page.
If you need your pages to be conditionally uncached based on the presence of your cookie, please contact Support from your User Portal for assistance.
What are PHP Sessions?
PHP Sessions are bits of data about a user on your site, meant to stick with users as they navigate your site. A PHP Session involves setting a cookie specifically called PHPSESSID with a unique identification string as the value. A common example would be storing shopping cart data, recently viewed items, or an authentication across multiple pages.
If PHP Sessions are a type of cookie, what’s the problem?
The biggest conflict when using PHP Sessions has to do with the unique session identifiers. Because every user’s identification string is unique, this “busts cache” with every new user to visit your site. This kind of a system will not scale with many concurrent site users! With that in mind, our system specifically ignores headers defining a PHPSESSID cookie.
Beyond the performance and scaling implications, PHP Sessions present other problems. By default, PHP Sessions store data to the filesystem as their own unique file. Writing data to a file is an I/O process, and these kinds of processes are known to back up and cause high server load if your site gets too many concurrent users. Not to mention, this kind of session storage simply doesn’t work if your site is on a clustered solution spanning multiple web servers.
Not to mention, there are multiple security vulnerabilities centering around PHP Sessions. Vulnerabilities include Session data being exposed, Session fixation, and Session hijacking.
But I need Session data!
Before you panic, don’t worry just yet. Firstly, WordPress itself specifically does not use PHP Sessions, and instead relies heavily on other cookies. These days, most plugin and theme authors have opened their eyes to the problematic nature and insecurity of using PHP Sessions. The reality is, there’s a better way to store user session data! The correct method is to use the database to store session data. WooCommerce and other eCommerce solutions have already converted to using this method over traditional PHP Sessions, and also use their own cookie naming conventions.
If you look through your site’s code and see a plugin or theme file that uses session_start, your first step should be to check if an update is available. Be sure to update to the latest version and check again. If your plugin or theme does not have an update available, we recommend reaching out to the developer to ask why, and inquire about a more secure method.