Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction (the skippable part)

If you are an experienced PHP developer, you know that in order to optimize your application, eventually you need to peek "behind the curtains". This gives you better understanding of what your PHP and/or your web server are actually doing, when you think that they are working hard on producing your web page. And you find yourself in Profiling, in Zend Server Code Tracing, looking at Z-Ray or even at the logs.

...

Suspense music reaches its climax…

Session Locking

Many developers don't realize or choose to ignore this behavior of sessions. Which is easy to do – PHP makes session handling convenient for developers. Unfortunately, you learn about $_SESSION and accompanying handful of functions very early in your PHP study. And you get used to how simple and transparent this magic is. You learn it so early, that even when you’re a better developer, you rarely doubt this magic.

...

if request #1 takes 20 seconds (user authentication)
and request #2 takes 30 seconds (DB access)
and request #3 takes 25 seconds (external web service),
request #4 can get access to this session only 75 seconds after it came in.

...

iconfalse

Image Modified

What are the right things to do?

  • Close the session as early as possible - explicitly withsession_write_close(). Don't wait for the session to close automatically at the end of the request. This way your request may still take 30 seconds, but the session will only be locked for several milliseconds, allowing the next request to proceed.

    Info
    iconfalse

    Image Modified


  • As strange as it sounds - avoid using session_start() and $_SESSION. This will automatically lead to healthy parallel programming practices. For example, you can replace session_start() with session_get():
Code Block
languagephp
themeEclipse
Note
iconfalse
   function session_get() {
      	global $SessionData;
      	session_start();
      	session_write_close();
      	$SessionData = $_SESSION;
   }


Even if you have to write to the session at the end of the request, you should close it early and reopen at the end of the request. This doesn't make sense in linear paradigm, but in parallel programming it looks like this:

...

For example, you can introduce session_set():

Code Block
languagephp
themeEclipse
Note
iconfalse
   function session_set() {
      	global $SessionData;
      	session_start();
      	$_SESSION = $SessionData;
      	session_write_close();
   }


  • Don't write to the session too often. In general, don't consider the session a variable that keeps information between requests. In many cases, it is cheaper to get the information again than to write it to the session.
  • To the previous point, but also to performance in general - make sure you include caching in your architecture.

    For example, if you go to an external web service to fetch the weather, there is no reason to do this for each user from Berlin - do this once every 30 minutes, when the cached information expires.

    In the same way, maybe you really don't need to save anything in the session, except the user's ID - the rest you can save in cache or in the database. If you use Zend Server, Zend Data Cache would be a sound choice, anyway there is no lack of caching solutions for PHP.

Disclaimer

Please do not take the recommendations and especially the code samples in this article literally. Although the theory behind this article is correct, real life is usually different from theory and we often need to settle for "good practices" instead of implementing "best practices".

...