Over at ClassicWines, we recently experienced a login issue, where data was not being saved to the session after submitting valid credentials. Enter your username, password, and you would end up back at the home page as if nothing happened. I was banging my head against my desk (literally) looking for the cause.
Cut to the happy ending: PHP introduced a new “feature” that deconstructs objects BEFORE writing and closing the session. This means that if you use classes to manage your sessions, those classes are gone before the script executes your methods to save the session. There’s a warning at the bottom of the PHP manual page for session_set_save_handler() that identifies the issue succinctly.
For anyone who ended up here looking for help, the workaround is to call session_write_close() before the classes are deconstructed, usually with a combination of the __destruct() magic method and register_shutdown_function(). PHP documentation claims it was introduced in v5.0.5, but I did not have this issue using v5.1.2. If you like examples, Zen Cart built in a fix in the latest versions of their package.
This is a small example of a much larger problem in our industry: blind devotion to “the rules.” Technically speaking, the PHP team’s decision was correct: items loaded into memory should be destroyed in the reverse order in which they were created. It’s typically a good assumption to make, because often the younger processes were spawned by and rely on the ones that came before it.
But in this situation it makes absolutely no practical sense. I need my classes in order to close the session properly (as do many developers), and so ideally they should exist when I need them. This is, in fact, the way things worked prior to the bug fix.
The documentation warning I mentioned above even describes the situation as a “chicken and egg” problem, indicating some tacit acceptance of the fact that you cannot have one without the other. The case can be made for either one taking priority.
All that being the case, why make the change at all? It did not make anyone’s life easier. Quite the opposite, in fact. The new setup requires more logic, and hence more lines of code, to write and maintain. The fact that the session came first in the load order is totally irrelevant. Breaking the order of destruction is merely a break in convention, nothing more.
It’s a classic case of architecture astronauts.
When you go too far up, abstraction-wise, you run out of oxygen. Sometimes smart thinkers just don’t know when to stop, and they create these absurd, all-encompassing, high-level pictures of the universe that are all good and fine, but don’t actually mean anything at all.
The PHP team is, by nature, a pretty high-floating group. To a certain extent, it’s to be expected; they’re writing a programming language, after all. But this decision definitely shows a lack of oxygen.
My number one concern is always making my code do what it needs to do in the most efficient way possible. If that breaks a socially accepted norm or two, I have absolutely no problem with it, and neither should you.