Welcome to Dream.In.Code
Getting PHP Help is Easy!

Join 107,388 PHP Programmers for FREE! Ask your question and get quick answers from experts. There are 1,700 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



Issue with sessions in db. More than one and same id?

 
Reply to this topicStart new topic

Issue with sessions in db. More than one and same id?

Dancia
post 3 Jul, 2008 - 12:55 PM
Post #1


D.I.C Head

**
Joined: 15 Jun, 2008
Posts: 53



Thanked 1 times
My Contributions


Ok im using this code for writing to db:
php

<?
class session
{
/* Define the mysql table you wish to use with
this class, this table MUST exist. */
var $ses_table = "sessions";

/* Change to 'Y' if you want to connect to a db in
the _open function */
var $db_con = "Y";

/* Configure the info to connect to MySQL, only required
if $db_con is set to 'Y' */
var $db_host = "localhost";
var $db_user = "root";
var $db_pass = "";
var $db_dbase = "alpha";

/* Create a connection to a database */
function db_connects() {
$mysql_connect = @mysql_connect ($this->db_host,
$this->db_user,
$this->db_pass);
$mysql_db = @mysql_select_db ($this->db_dbase);

if (!$mysql_connect || !$mysql_db) {
return FALSE;
} else {
return TRUE;
}
}

/* Open session, if you have your own db connection
code, put it in here! */
function _open($path, $name) {
if ($this->db_con == "Y") {
$this->db_connects();
}

return TRUE;
}

/* Close session */
function _close() {
/* This is used for a manual call of the
session gc function */
$this->_gc(0);
return TRUE;
}

/* Read session data from database */
function _read($ses_id) {
$this->db_connects();
$session_sql = "SELECT * FROM " . $this->ses_table
. " WHERE ses_id = '$ses_id'";
$session_res = mysql_query($session_sql);
if (!$session_res) {
return '';
}

$session_num = mysql_num_rows ($session_res);
if ($session_num > 0) {
$session_row = mysql_fetch_assoc ($session_res);
$ses_data = $session_row["ses_value"];
return $ses_data;
} else {
return '';
}
}
/* Write new data to database */
function _write($ses_id, $data) {
$this->db_connects();
$session_sql = "UPDATE " . $this->ses_table
. " SET ses_time='" . time()
. "', ses_value='".addslashes($data)."' WHERE ses_id='$ses_id'";
$session_res = mysql_query ($session_sql) or die('Query failed: ' . mysql_error().'<br>'.$session_sql);
if (!$session_res) {
return FALSE;
}
if (mysql_affected_rows ()) {
return TRUE;
}

$session_sql = "INSERT INTO " . $this->ses_table
. " (ses_id, ses_time, ses_start, ses_value)"
. " VALUES ('$ses_id', '" . time()
. "', '" . time() . "', '$data')";
$session_res = mysql_query ($session_sql);
if (!$session_res) {
return FALSE;
} else {
return TRUE;
}
}

/* Destroy session record in database */
function _destroy($ses_id) {
$this->db_connects();
$session_sql = "DELETE FROM " . $this->ses_table
. " WHERE ses_id = '$ses_id'";
$session_res = mysql_query ($session_sql);
if (!$session_res) {
return FALSE;
} else {
return TRUE;
}
}

/* Garbage collection, deletes old sessions */
function _gc($life) {
$this->db_connects();
$ses_life = strtotime("-2 hours");

$session_sql = "DELETE FROM " . $this->ses_table
. " WHERE ses_time < $ses_life";
$session_res = mysql_query ($session_sql);


if (!$session_res) {
return FALSE;
} else {
return TRUE;
}
}
}
?>


And handler:
php

/* Create new object of class */
$ses_class = new session();

/* Change the save_handler to use the class functions */
session_set_save_handler (array(&$ses_class, '_open'),
array(&$ses_class, '_close'),
array(&$ses_class, '_read'),
array(&$ses_class, '_write'),
array(&$ses_class, '_destroy'),
array(&$ses_class, '_gc'));
/* Start the session */


I have attached my issue.


Maybe im using it in wrong way?
Can I add session like: $_SESSION['new_sess'];
Or do i have to call it from class and how? ;/

P.S. Yes - it does clean garbage after some time.
Attached Image

Also i want to say that this kind of stuff happens only sometimes.

This post has been edited by Dancia: 3 Jul, 2008 - 01:05 PM
User is offlineProfile CardPM

Go to the top of the page


Martyr2
post 6 Jul, 2008 - 01:39 PM
Post #2


Programming Theoretician

Group Icon
Joined: 18 Apr, 2007
Posts: 4,270



Thanked 72 times

Expert In: C/C++, Java, VB, VB.NET, C#, PHP, Web Development, HTML & CSS, Javascript

My Contributions


Well I think you might be suffering from a little known problem with regards to updating and how PHP mysql_affected_rows responds. Here is the questionable part...

"When using UPDATE, MySQL will not update columns where the new value is the same as the old value. This creates the possibility that mysql_affected_rows() may not actually equal the number of rows matched, only the number of rows that were literally affected by the query. " - PHP.net for mysql_affected_rows function

So lets say you have one record with the session id, time start and value. The process then fires again for the _write where it determines that the session id and time are the same as the record already there. It will execute the update, but not update that existing record.

This results in the update command being executed so mysql_query will return true avoiding your first if statement, but since no records were actually updated it would return "0" making second if statement (where you check mysql_affected_rows) false. Thus it bypasses both your if statements and goes straight to the insert.

Now this would also explain why you see it only sometimes because as soon as the time changes, it will update the one record just fine and work as expected.

This is a general theory so what I would do to see if it fixes it is that instead of just running the update, first pull the id of that record (assuming your records have an id field that increments... if not you should make sure you have one in) using a select statement, if you found a record, issue the update on that record. If you didn't find the record, issue the insert.

Return true if an update or insert was done, false otherwise.

That should scoot you past this issue. smile.gif

This post has been edited by Martyr2: 6 Jul, 2008 - 01:42 PM
User is offlineProfile CardPM

Go to the top of the page

Fast ReplyReply to this topicStart new topic
Time is now: 8/28/08 02:18PM

Live PHP Help!

PHP Tutorials

Reference Sheets

PHP Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month