jebriggsy Posted September 17, 2014 Share Posted September 17, 2014 Hello, I'm writing a quick roll-your-own blog to get back into the swing of webdev, and I've hit a snag. I'm trying to use session_set_save_handler to use a custom class of functions, implementing SessionHandlerInterface, to save sessions to a PostgreSQL database table via PDO. I've added die() at every point I think it could be failing but no errors are reported. I checked nginx, php-fpm, and postmaster logs, nothing. The thing I'm trying to debug is the fact that no rows are inserted to the database after setting a random test variable in $_SESSION and calling session_write_close(). I know the script is successfully connecting to the database because no exceptions or errors are thrown, so there must be some error that isn't being reported by PDO or the session handler. Basically PDOStatement::rowCount() is returning > 0 for a query inserting a row into the sessions table but upon a SELECT * on said table nothing is there. So I've attached/bpaste'd the relevant files. Here's what's in them: index.php: the script that runs everything database.php: database functionality main.php: instantiates database for session & other classes. also contains the function to test session/database functionality sessions.php: class implementing SessionHandlerInterface SQL for the sessions table: CREATE TABLE sessions ( session_id bytea PRIMARY KEY, session_expires integer NOT NULL, session_data text NOT NULL, session_ip varchar(39) NOT NULL, user_id integer ); Any help or insight would be much appreciated.index.php database.php main.php sessions.php Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted September 17, 2014 Share Posted September 17, 2014 A custom session handler is pretty much the worst starting point you can think of, because even experienced developers constantly get this wrong. And indeed this is a typical naïve implementation without any concurrency handling whatsoever. Using Ajax or running a slow script multiple times in quick succession is enough to break the whole thing and end up with strange errors. Proper session handlers are much more complex and require a deep understanding of how to handle concurrency at database level (locks, transactions etc.). For the time being, just stick to classical file-based sessions. Or if you absolutely must store the sessions in the database, use an existing implementation which actually works (there aren't many). For example, the Symfony framework gets it right. They're using advisory locks to make sure that concurrent requests won't overwrite each other. Quote Link to comment Share on other sites More sharing options...
jebriggsy Posted September 17, 2014 Author Share Posted September 17, 2014 (edited) A custom session handler is pretty much the worst starting point you can think of, because even experienced developers constantly get this wrong. And indeed this is a typical naïve implementation without any concurrency handling whatsoever. Using Ajax or running a slow script multiple times in quick succession is enough to break the whole thing and end up with strange errors. I think you may be underestimating my level of competency. I'm doing this project to buff out rust not re-learn basics. I'm not a complete noob, just someone who hasn't done serious coding in a year or three. I intended to implement transactions once I had the basic prototype working. I don't need concurrency when I'm the only one using the software at the moment and nowhere near the point where I'm writing AJAX requests Indeed, eventually I will implement stored procedures, transactions, GPG-based two-factor auth, and maybe a bit of OAuth if I'm feeling adventurous. I'm just stuck on why PDO/PostgreSQL is returning > 0 affected rows on an INSERT that has obviously failed because the table is empty and yet hasn't thrown any exceptions, errors, notices, or warnings. I've always used MySQL and Apache with custom-rolled auth and session systems. I chose a project implementing SessionHandlerInterface using PostgreSQL and Nginx specifically to avoid using old habits that are probably outdated and force me to catch up with modern techniques and design flows. And specifically avoiding frameworks so as to develop a deeper understanding of the concepts. Edited September 17, 2014 by jebriggsy Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted September 17, 2014 Share Posted September 17, 2014 the error is most likely in your main.php/sesstest() method - $count = $this->db->exec('SELECT * FROM sessions'); the pdo ->exec() method does NOT return results for a SELECT query and since a select query does not affect any rows, this usage will always return a zero, which is probably what you are basing the statement that the table is empty on. only insert, delete, update, and replace queries affect rows. you would need to get a row count using a method available for PostgreSQL (which i am not well versed with.) if you cannot get a count in the query statement, doing a pdo fetchall() of the result set and using php count() of the resultant array is the most universal method that would work with all database types. edit: if the PDOStatement::rowCount() method works for PostgreSQL, you would use the pdo query() method to run the query and get a count of the number of rows. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted September 17, 2014 Share Posted September 17, 2014 I think you may be underestimating my level of competency. And I think you're overestimating it. The concept is simply naïve, sorry. You have two options now: You can build some half-assed amateur solution with the help of PHP Freaks. Or you can adopt a professional solution from people who actually know what they're doing (like the Symfony team). Most PHP programmers go with the half-assed solution, which is why they stay amateur programmers for their entire life. But maybe you're one of the few people who takes their job seriously and wants to do it right. Your choice. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.