javascript - php session is randomly lost and cant understand why -


i paid programmer make shop basket script work spreadshirt api. working perfectly, except basket keeps emptying itself. think session lost @ point script creates basketid.

i tried find if there specific reason happening, without success... can't reproduce bug. happens randomly without reason. closing browser, resetting apache or whole webserver won't provoke session lost.

i've got 2 different scripts working cookies on same domain , don't have problem (one cookie admin login session , other cookie save user's last viewed articles on shop)

i tried solutions found on google without success : editing php.ini , forcing ini settings through php, tried htaccess way, ...

here's "sessions" part of phpinfo: http://gyazo.com/168e2144ddd9ee368a05754dfd463021

shop-ajax.php (session handling @ line 18)

ini_set('session.cookie_domain', '.mywebsite.com' ); header("pragma: no-cache"); header("cache-control: no-store, no-cache, max-age=0, must-revalidate"); $language = addslashes($_get['l']); $shopid = addslashes($_get['shop']);   // if($_server['http_x_requested_with'] != 'xmlhttprequest') { //  die("no direct access allowed"); // }    if(!session_id()) {   $lifetime=60 * 60 * 24 * 365;   $domain = ".mywebsite.com";    session_set_cookie_params($lifetime,"/",$domain);     @session_start(); }      // configuration $config['shopsource'] = "com"; $config['shopid'] = $shopid; $config['shopkey'] = "*****"; $config['shopsecret'] = "*****";    /*  * add article basket */ if (isset($_post['size']) && isset($_post['appearance']) && isset($_post['quantity'])) {     /*      * create new basket if not exist     */     if (!isset($_session['basketurl'])) {         /*          * shop xml         */         $stringapiurl = 'http://api.spreadshirt.'.$config['shopsource'].'/api/v1/shops/' . $config['shopid'];         $stringxmlshop = oldhttprequest($stringapiurl, null, 'get');         if ($stringxmlshop[0]!='<') die($stringxmlshop);         $objshop = new simplexmlelement($stringxmlshop);         if (!is_object($objshop)) die('basket not loaded');          /*          * create basket         */         $namespaces = $objshop->getnamespaces(true);         $basketurl = createbasket('net', $objshop, $namespaces);         $_session['basketurl'] = $basketurl;         $_session['namespaces'] = $namespaces;          /*          * checkout url         */         $checkouturl = checkout($_session['basketurl'], $_session['namespaces']);          // basket language workaround         if ($language=="fr") {             if (!strstr($checkouturl,'/fr')) {                 $checkouturl = str_replace("spreadshirt.com","spreadshirt.com/fr",$checkouturl);             }         }          $_session['checkouturl'] = $checkouturl;      }        /*     workaround not having appearance id :(     */     if ($_post['appearance']==0) {         $stringapiarticleurl = 'http://api.spreadshirt.'.$config['shopsource'].'/api/v1/shops/' . $config['shopid'].'/articles/'.intval($_post['article']).'?fulldata=true';         $stringxmlarticle = oldhttprequest($stringapiarticleurl, null, 'get');         if ($stringxmlarticle[0]!='<') die($stringxmlarticle);         $objarticleshop = new simplexmlelement($stringxmlarticle);         if (!is_object($objarticleshop)) die('article not loaded');         $_post['appearance'] = intval($objarticleshop->product->appearance['id']);     }       /*      * article data sent basket resource     */     $data = array(              'articleid' => intval($_post['article']),             'size' => intval($_post['size']),             'appearance' => intval($_post['appearance']),             'quantity' => intval($_post['quantity']),             'shopid' => $config['shopid']      );      /*      * add basket     */     addbasketitem($_session['basketurl'] , $_session['namespaces'] , $data);      $basketdata = preparebasket();       echo json_encode(array("c" => array("u" => $_session['checkouturl'],"q" => $basketdata[0],"l" => $basketdata[1]))); }     // no call, read basket if not empty if (isset($_get['basket'])) {     if (array_key_exists('basketurl',$_session) && !empty($_session['basketurl'])) {          $basketdata = preparebasket();          echo json_encode(array("c" => array("u" => $_session['checkouturl'],"q" => $basketdata[0],"l" => $basketdata[1])));     } else {         echo json_encode(array("c" => array("u" => "","q" => 0,"l" => "")));     } }       function preparebasket() {      $intinbasket=0;      if (isset($_session['basketurl'])) {         $basketitems=getbasket($_session['basketurl']);          if(!empty($basketitems)) {             foreach($basketitems->basketitems->basketitem $item) {                 $intinbasket += $item->quantity;             }         }     }      $l = "";     $pq = parse_url($_session['checkouturl']);     if (preg_match("#^basketid\=([0-9a-f\-])*$#i", $pq['query'])) {         $l = $pq['query'];     }      return array($intinbasket,$l); }        // additional functions function addbasketitem($basketurl, $namespaces, $data) {     global $config;      $basketitemsurl = $basketurl . "/items";      $basketitem = new simplexmlelement('<?xml version="1.0" encoding="utf-8" standalone="yes"?>             <basketitem xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://api.spreadshirt.net">             <quantity>' . $data['quantity'] . '</quantity>             <element id="' . $data['articleid'] . '" type="sprd:article" xlink:href="http://api.spreadshirt.'.$config['shopsource'].'/api/v1/shops/' . $data['shopid'] . '/articles/' . $data['articleid'] . '">             <properties>             <property key="appearance">' . $data['appearance'] . '</property>             <property key="size">' . $data['size'] . '</property>             </properties>             </element>             <links>             <link type="edit" xlink:href="http://' . $data['shopid'] .'.spreadshirt.' .$config['shopsource'].'/-a' . $data['articleid'] . '"/>             <link type="continueshopping" xlink:href="http://' . $data['shopid'].'.spreadshirt.'.$config['shopsource'].'"/>             </links>             </basketitem>');      $header = array();     $header[] = createauthheader("post", $basketitemsurl);     $header[] = "content-type: application/xml";     $result = oldhttprequest($basketitemsurl, $header, 'post', $basketitem->asxml()); }    function createbasket($platform, $shop, $namespaces) {      $basket = new simplexmlelement('<basket xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://api.spreadshirt.net">             <shop id="' . $shop['id'] . '"/>             </basket>');      $attributes = $shop->baskets->attributes($namespaces['xlink']);     $basketsurl = $attributes->href;     $header = array();     $header[] = createauthheader("post", $basketsurl);     $header[] = "content-type: application/xml";     $result = oldhttprequest($basketsurl, $header, 'post', $basket->asxml());     $basketurl = parsehttpheaders($result, "location");      return $basketurl;  }       function checkout($basketurl, $namespaces) {      $basketcheckouturl = $basketurl . "/checkout";     $header = array();     $header[] = createauthheader("get", $basketcheckouturl);     $header[] = "content-type: application/xml";     $result = oldhttprequest($basketcheckouturl, $header, 'get');     $checkoutref = new simplexmlelement($result);     $refattributes = $checkoutref->attributes($namespaces['xlink']);     $checkouturl = (string)$refattributes->href;      return $checkouturl;  }  /*  * functions build headers */ function createauthheader($method, $url) {     global $config;      $time = time() *1000;     $data = "$method $url $time";     $sig = sha1("$data ".$config['shopsecret']);      return "authorization: sprdauth apikey=\"".$config['shopkey']."\", data=\"$data\", sig=\"$sig\"";  }   function parsehttpheaders($header, $headername) {      $retval = array();     $fields = explode("\r\n", preg_replace('/\x0d\x0a[\x09\x20]+/', ' ', $header));      foreach($fields $field) {          if (preg_match('/(' . $headername . '): (.+)/m', $field, $match)) {             return $match[2];         }      }      return $retval;  }  function getbasket($basketurl) {      $header = array();     $basket = "";      if (!empty($basketurl)) {         $header[] = createauthheader("get", $basketurl);         $header[] = "content-type: application/xml";         $result = oldhttprequest($basketurl, $header, 'get');         $basket = new simplexmlelement($result);     }      return $basket;  }     function oldhttprequest($url, $header = null, $method = 'get', $data = null, $len = null) {      switch ($method) {          case 'get':              $ch = curl_init($url);             curl_setopt($ch, curlopt_http_version, curl_http_version_1_1);             curl_setopt($ch, curlopt_returntransfer, true);             curl_setopt($ch, curlopt_header, false);              if (!is_null($header)) curl_setopt($ch, curlopt_httpheader, $header);              break;          case 'post':              $ch = curl_init($url);             curl_setopt($ch, curlopt_http_version, curl_http_version_1_1);             curl_setopt($ch, curlopt_returntransfer, true);             curl_setopt($ch, curlopt_header, true);             curl_setopt($ch, curlopt_httpheader, $header);             curl_setopt($ch, curlopt_post, true); //not createbasket addbasketitem             curl_setopt($ch, curlopt_postfields, $data);              break;      }      $result = curl_exec($ch);     curl_close($ch);      return $result;  } ?> 

there's 2 other parts of script : form add sample tshirt basket (example.php) , script call ajax (shop-controller.js). can post if needed there's no session handling stuff.

update - maybe problem not related sessions. basketid lost, phpsessid stays same in browser cookies.

i did following tests last 3 days (tested diferent computers , browsers):

  • empty browser cookies start new session during afternoon

  • add 1 item basket, write down basketid , check browsers cookies write down phpsessid

  • usually around midnight, basket empty itself

  • phpsessid stays same in browser cookies, after basket empty itself

  • however basketid not same, 1 used during afternoon lost , new 1 regenerated

server centos 5.9 - php version 5.2.9 (from ovh). dedicated server on dedicated ip.

first need find if problem in session's garbage collection or logical error within code. that, can:

// add right after session_start() if (!isset($_session['mysessioncheck'])) {     $_session['mysessioncheck'] = "this session (" . session_id() . ") started " . date("y-m-d h:i:s"); }  // html pages, add this: echo '<!-- ' . $_session['mysessioncheck'] . ' -->';  // ajax pages, add "mysessioncheck" json response: echo json_encode(     array(         "c" => array(             "u" => $_session['checkouturl'],             "q" => $basketdata[0],             "l" => $basketdata[1]         ),         "mysessioncheck" => $_session['mysessioncheck']     ) ); 

if message changes @ same time basket empties, you'll know sure it's problem php sessions.

in case, there few things can try:

1) doing

$lifetime=60 * 60 * 24 * 365; $domain = ".mywebsite.com"; session_set_cookie_params($lifetime,"/",$domain); @session_start(); 

but according user contributed note php.net docs:

php's session control not handle session lifetimes correctly when using session_set_cookie_params().

so may try using setcookie() instead:

$lifetime=60 * 60 * 24 * 365; session_start(); setcookie(session_name(),session_id(),time()+$lifetime); 

even though it's 4 year old note pointed in comments, tested , still happens (i'm on php 5.5.7, windows server 2008, iis/7.5). setcookie() produced http headers change expiring date (example setting $lifetime 600):

set-cookie: phpsessid=(the id); expires=mon, 22-jun-2015 15:03:17 gmt; max-age=600 

2) if you're using debian servers or derivative, use cron job clear out php sessions, might try:

3) find out if there process clearing sessions, can place watch on directory session files stored (actual path varies server server, use session_save_path find out location on yours). i'm no server admin, i've read can use auditctl that, make sure log who made changes files.

4) if don't have access server configuration, or don't want depend on server config (good if switch hosts), can implement own session handler. check out example pedro gimeno.


Comments

Popular posts from this blog

How to connect android app to App engine -

gcc - MinGW's ld cannot perform PE operations on non PE output file -

php - display validation error message next to the textbox in codeigniter -