23.12.2012 Posted April 22, 2010 Share Posted April 22, 2010 I am trying to implement database-powered sessions in a modularized web site, using object-oriented MySQL. But I get errors reading Fatal error: Call to a member function real_escape_string() on a non-object in /Applications/MAMP/htdocs/sandbox/config/sessions.php on line 91Fatal error: Call to a member function close() on a non-object in /Applications/MAMP/htdocs/sandbox/config/sessions.php on line 50 All the custom sessions functions work, except for the closing and writing ones. Here are the database configuration file and the sessions configuration file. I've been struggling for hours and I can't get it to work. I'm using PHP 5.3.2 and MySQL 5.1.44 with Apache 2.0.63 <?php # /config/mysql.php// Define the database hostnamedefine('DB_HOST', 'localhost');// Define the database usernamedefine('DB_USER', 'cezar');// Define the database passworddefine('DB_PASS', 'parola');// Define the database namedefine('DB_NAME', 'sangym');// Define the database portdefine('DB_PORT', 3306);// Define the database socketdefine('DB_SOCK', '/Applications/MAMP/tmp/mysql/mysql.sock');// Connect to the database using mysqli_connect()// Store the database connection in a $db_conn variable$db_conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT, DB_SOCK);if($db_conn->connect_error) { die('Connect Error (' . $db_conn->connect_errno . ') ' . $db_conn->connect_error);}?> <?php # /config/sessions.php// Require the main configuration filerequire_once('./config/main.php');// Require the database configuration filerequire_once(DB);function sangym_session_open() { global $db_conn; // Return true upon success return true;} // end of 'sangym_session_open' functionfunction sangym_session_close() { global $db_conn; // Close the database connection return $db_conn->close();} // end of 'sangym_session_close' functionfunction sangym_session_read($sid) { global $db_conn; // Getting the 'data' column for the row whose // ID is passed as an argument to the function $db_query = sprintf('SELECT data FROM sessions WHERE id="%s"', $db_conn->real_escape_string($sid)); $db_result = $db_conn->query($db_query); // If there is any data associated with the session ID passed // get the data and return it. Otherwise, return an empty string if($db_result->num_rows == 1) { // Getting the data list($data) = $db_result->fetch_array(MYSQLI_NUM); // Returning the data return $data; } else { // Return an empty string return ''; } // end of data return} // end of 'sangym_session_read' functionfunction sangym_session_write($sid, $data) { global $db_conn; // Replace the existing information in the database // with the ones provided as arguments to the function $db_query = sprintf('REPLACE INTO sessions(id, data) VALUES("%s", "%s")', $db_conn->real_escape_string($sid), $db_conn->real_escape_string($data)); $db_result = $db_conn->query($db_query); // Return the number of affected rows return $db_conn->affected_rows;} // end of 'sangym_session_write' functionfunction sangym_session_destroy($sid) { global $db_conn; // Delete the data from 'sessions' where the ID // is the one passed as argument to the function $db_query = sprintf('DELETE FROM sessions WHERE id="%s"', $db_conn->real_escape_string($sid)); $db_result = $db_conn->query($db_query); // Cleare the $_SESSION array $_SESSION = array(); // Return the number of affected rows return $db_result->affected_rows;} // end of 'sangym_session_destroy' functionfunction sangym_session_gbc($expire) { global $db_conn; // Deleting expired sessions from the database $db_query = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accessed, INTERVAL %d SECOND) < NOW()', (int) $db_conn->real_escape_string($expire)); $db_result = $db_conn->query($db_query); // Return the number of affected rows return $db_conn->affected_rows;} // end of 'sangym_session_gbc' function// Declare the functions to usesession_set_save_handler('sangym_session_open', 'sangym_session_close', 'sangym_session_read', 'sangym_session_write', 'sangym_session_destroy', 'sangym_session_gbc');// Start the sessionssession_start();// Attempt loginif(!isset($_SESSION['id'])) { if(isset($_COOKIE['id']) && isset($_COOKIE['username'])) { $_SESSION['id'] = $_COOKIE['id']; $_SESSION['username'] = $_COOKIE['username']; $logged_in = true; } else { $logged_in = false; }} else { $logged_in = true;}?> Link to comment Share on other sites More sharing options...
justsomeguy Posted April 22, 2010 Share Posted April 22, 2010 It sounds like the $db_conn variable is being overwritten by something else at some point. I don't see that happening in this code. Link to comment Share on other sites More sharing options...
23.12.2012 Posted April 22, 2010 Author Share Posted April 22, 2010 That was also my assumption, but I can't see what would overwrite it. It might be some OOP error I'm making, I think I'll rewrite the database interaction using procedural PHP, and see if it persists. Link to comment Share on other sites More sharing options...
justsomeguy Posted April 22, 2010 Share Posted April 22, 2010 You aren't using a variable called $db_conn in any of your other code? If you ever have that on the left side of an equal sign that's going to cause this. Link to comment Share on other sites More sharing options...
23.12.2012 Posted April 22, 2010 Author Share Posted April 22, 2010 Well, actually, I think it might be related to OOP. After having another look over the session_set_save_handler() documentation, I read this: As of PHP 5.0.5 the write and close handlers are called after object destruction and therefore cannot use objects or throw exceptions. The object destructors can however use sessions. So is PHP 5 not supporting OOP database functions? Link to comment Share on other sites More sharing options...
justsomeguy Posted April 22, 2010 Share Posted April 22, 2010 So is PHP 5 not supporting OOP database functions?That's not what that means, that means that PHP destroys all classes, including the MySQLi class, before ending the session. If that is what is happening, then you won't be able to use a class in your session handlers, you'll need to use the procedural method. Link to comment Share on other sites More sharing options...
23.12.2012 Posted April 22, 2010 Author Share Posted April 22, 2010 I'm sorry, I've written that the wrong way, I wanted to say that it does not support OOP database session handling. Link to comment Share on other sites More sharing options...
justsomeguy Posted April 22, 2010 Share Posted April 22, 2010 If the session is the last thing to go, then yeah there's no way to use a class in a session. The reason for that is because you are able to use the session in your class, if they destroyed the session before they destroyed the class then you wouldn't be able to use the session in the class destructor, so it's either one or the other and this is the way they chose. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.