ID:               20449
 Comment by:       [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
 Status:           Feedback
 Bug Type:         Session related
 Operating System: redhat 7.3
 PHP Version:      4.3.0-dev
 New Comment:

here is my session save handler.  Pretty much taken from phpbuilder.com
article.

Important to note that I have never seen a mysql error in my php_errors
log.

<?
$GLOBALS["SESS_DBHOST"] = "not shown";      /* database server hostname
*/
$GLOBALS["SESS_DBNAME"] = "not shown";     /* database name */
$GLOBALS["SESS_DBUSER"] = "not shown";   /* database user */
$GLOBALS["SESS_DBPASS"] = "not shown";   /* database password */

$GLOBALS["SESS_DBH"] = "";

$GLOBALS["SESS_LIFE"] = 5400;

function sess_open($save_path, $session_name) 
  {
    if (!$GLOBALS["SESS_DBH"] = mysql_pconnect($GLOBALS["SESS_DBHOST"],
$GLOBALS["SESS_DBUSER"], $GLOBALS["SESS_DBPASS"])) 
      {
        echo "<li>Can't connect to " . $GLOBALS["SESS_DBHOST"] . " as "
. $GLOBALS["SESS_DBUSER"];
        echo "<li>MySQL Error: ", mysql_error();
        die;
      }

    if (! mysql_select_db($GLOBALS["SESS_DBNAME"],
$GLOBALS["SESS_DBH"]))
      {
        echo "<li>Unable to select database " .
$GLOBALS["SESS_DBNAME"];
        die;
      }

    return true;
  }

function sess_close() 
  {
    return true;
  }

function sess_read($key) 
  {
    $qry = "SELECT value FROM sessions WHERE sesskey = '$key' AND
expiry > " . time();
    $qid = mysql_query($qry, $GLOBALS["SESS_DBH"]);

    if (list($value) = mysql_fetch_row($qid)) 
      {
        return $value;
      }

    return "";
  }

function sess_write($key, $val) 
  {
    $expiry = time() + $GLOBALS["SESS_LIFE"];
    $value = addslashes($val);

    $qry = "INSERT INTO sessions VALUES ('$key', $expiry, '$value')";
    $qid = mysql_query($qry, $GLOBALS["SESS_DBH"]);

    if (! $qid) 
      {
        $qry = "UPDATE sessions SET expiry = $expiry, value = '$value'
WHERE sesskey = '$key' AND expiry > " . time();
        $qid = mysql_query($qry, $GLOBALS["SESS_DBH"]);
      }

    return $qid;
  }

function sess_destroy($key) 
  {
    $qry = "DELETE FROM sessions WHERE sesskey = '$key'";
    $qid = mysql_query($qry, $GLOBALS["SESS_DBH"]);

    return $qid;
  }

function sess_gc($maxlifetime) 
  {
    $qry = "DELETE FROM sessions WHERE expiry < " . time();
    $qid = mysql_query($qry, $GLOBALS["SESS_DBH"]);

    return mysql_affected_rows($GLOBALS["SESS_DBH"]);
  }

//now that we have defined everything, set the save handler
session_set_save_handler(
  "sess_open",
  "sess_close",
  "sess_read",
  "sess_write",
  "sess_destroy",
  "sess_gc");
?>


Previous Comments:
------------------------------------------------------------------------

[2002-11-17 12:13:59] [EMAIL PROTECTED]

Here is my cart script.  

The only special thing I do before this is to initiate the session.  I
always call session_id(an id) before session_start because I can't rely
on cookies.  The only time I do not call session_id is when the visitor
first comes to the site.

manage_products() is called on the cart.php page when a user either
adds an item or updates an item.

Also, cart.php is the only page that manipulates the cart.  Every other
page simply display cart info. (including the order page)

<?

  function print_cart()
    {
      include("cart_display.html");
    }

  function printMiniCart()
    {
      include("cart_mini_display.html");
    }

  function print_non_editable_cart()
    {
      include("cart_final_display.html");
    }

  function manage_products()
    {
      //get the product properties from the get or post variables
      $prod_id = $_POST["product_id"];
      $qty = $_POST["qty"];

      if(isset($_POST["options"]))
        $options = $_POST["options"];  //this is the case when
updating
      else
        $options = $_POST["color"] . "-" . $_POST["size"];

      //blow up the item if it is already in the cart
      if(isset($_SESSION["cart"][$prod_id]))
        {
          //product already in cart

          $products = explode("+++", $_SESSION["cart"][$prod_id]);
          $prc = count($products);
          $product_found = false;

          for($i=0; $i < $prc; $i++)
            {
              //now explode the inner workings of each subproduct
              $subproduct = explode("|", $products[$i]);

              //the array of subproduct looks like this
              //options = $subproduct[0];
              //qty = $subproduct[1];

              if($subproduct[0] == $options)
                {
                  //product being added is same as current subproduct.
                  //update the qty
                  $subproduct[1] = $qty;

                  $product_found = true;
                }

              //rebuild the subproduct
              $products[$i] = implode("|", $subproduct);
            }

          if(!$product_found)
            {
              //product configuration not found in cart.  add it to
cart
              $products[] = $options . "|" . $qty;
            }

          //rebuild the product string
          $_SESSION["cart"][$prod_id] = implode("+++", $products);
        }
      else
        {
          //easy case.  Product not in cart
          //simply add it
          //build the product identification string
          $products[] = $options . "|" . $qty;

          $_SESSION["cart"][$prod_id] = implode("+++", $products);
        }

      return true;
    }

?>

------------------------------------------------------------------------

[2002-11-17 12:06:13] [EMAIL PROTECTED]

ok.  This is really frustrating.  I wrote a script that simulates a
cart.  I use fopen once to add something to the cart, and a second time
to check the cart.  (I use uniqid to create a session id and pass it
through the url)

The script simulates it 100 times.  Then, via a interface and iframes,
I have six frames loading the test script.  

See - http://www.t-shirtking.com/temp/testcart.html

This raises the load a little.  However, as you will see, it checks out
everytime.

However, this morning I check my e-mail and find a dozen more messages
from the order page that tells me someones cart was empty.

Next message, I'm gonna show you my cart.  It isn't too complicated.

------------------------------------------------------------------------

[2002-11-17 11:07:55] [EMAIL PROTECTED]

I too can't reproduce this bug. Someones when someone uses the
Checksheet system the session dies after 15 minutes. I run back and we
repeat every step the person did leading up to the session that
disappears. Wait 15 minutes, do exactly the same thing, but this time
it works. Other times people leave it idle for 2 hours at a time and it
disappears, and sometimes it doesn't. But I have my sessions set not to
timeout, only after browser closes.  I haven't been doing anything
special. After the session 'disppears' I log onto the server and look
at the session save path directory for the session (in an attempt to
recover the data stored in it), and it's no longer there. I'll continue
to try and reproduce this bug and if I find anything I'll post here.

------------------------------------------------------------------------

[2002-11-16 20:33:38] [EMAIL PROTECTED]

Ok, I can only open or close this.  If you'd like, change it to
feedback.  I will provide more details soon.

I'm very anxious to help squash this problem.

------------------------------------------------------------------------

[2002-11-16 20:32:11] [EMAIL PROTECTED]

As for an example script...I don't think I could make it short. 
However, the script is only a shopping cart. I'm not doing anything out
of the ordinary.  It is a simple array of strings.  I try to store the
array as a session.  

Like I said before, I've never been able to break it myself.  However,
I do see evidence of it breaking. (ie. the e-mail that is sent to me)

I guess it should be possible to write a script that continuously tries
to add to cart then checkout and see if it would break that way.  

I will do so and get back to you.  In the meantime, I will change the
status of this to feedback.

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/20449

-- 
Edit this bug report at http://bugs.php.net/?id=20449&edit=1

Reply via email to