httpwebwitch - 1:44 pm on May 9, 2011 (gmt 0)
ahh, no sorry you're all wrong. on Friday I was debugging the garbage collection routine that prompts the expiry of a session.
>> I only happen if you don't attend. If you show up, I'm canceled.
if you refresh a page that's uses the session, the session doesn't expire. Looking at the contents of $_SESSION changes the session. It's rather schroedingeresque.
>> Sometimes cookies are served.
PHP's default session behaviour is to send a cookie header in the response
>> I produce no output, everything that happens in me is hidden
It's not the result of a normal request/response process prompted by a browser, so there's no convenient output, thus nothing that you can echo out to a browser to see if the process worked.
In this situation, most of your debugging methods won't work. Tricky stuff, because it happens only if the expiry lapses, and any hit to the session will extend it. To expire the session, you need to knock back the expiry on it (or else you're stuck waiting until it expires), then hit the server to trigger GC, but Not in a way that accesses your session (because that will extend the expiry again)
Overriding the default session behaviour is a finicky business, but there are situations when you need to get your hands dirty in it. For instance, when developing a server-side API that requires authentication, you'll likely want to store your sessions in a mysql database, not in /tmp files. This gives your app immediate access to the sessions, so your app can establish authentication for requests. It's also useful to override the session handler if your app accepts the session token as something other than a cookie, which is quite common if you're designing an app for something other than a web browser.
It's done using session_set_save_handler() [php.net]
So how do you debug a process that has no output, and happens outside the context of a browser-origin request?
one easy way: liberal use of error_log() [us.php.net]
error_log() sends a string into the error log. And viewing the real-time contents of your error log is quite simple. Go into an SSH terminal and navigate to your error log - it's often in /var/log/httpd/ - and do this command:
tail -f error_log
the "tail -f" is a great trick to know. It flows the data from error_log - any new appended lines - straight onto the screen. When that's running, you can trigger your session expiry (if you know how) and you'll see the output of error_log() appear in the terminal window.
If you don't want to use error_log, you can output to a file using file_put_contents() [php.net], with "FILE_APPEND" as the third argument. That accomplishes the same thing.
So why'd anyone need to hook into the garbage collection routine?
In my case there are connections to other servers that are established when a session is created, that needed to be forcibly closed when a session expires. So, in the "destroy" and "gc" parts of the session handler, I needed the handler to do a little extra work. This can only be done if you've overridden the default session handler with your own.
It's powerful stuff.