php会话随机丢失,无法理解为什么
我付钱给一个程序员制作一个购物篮脚本来使用Spreadshirt API。一切都很完美,除了篮子一直在清空自己。我认为会话在某个时候丢失了,因此脚本创建了另一个.BasketId
我试图找出它是否发生了一个具体的原因,没有任何成功......我无法重现该错误。它只是随机发生,没有任何理由。关闭浏览器,重置apache甚至整个Web服务器都不会引起会话丢失。
我有两个不同的脚本在同一个域上使用cookie,它们没有任何问题(一个是管理员登录会话的cookie,另一个是保存用户在商店上上次查看的文章)
我尝试了在谷歌上找到的所有解决方案,但没有任何成功:编辑,通过php强制ini设置,尝试了方法,...php.inihtaccess
这是我的phpinfo的“会话”部分:http://gyazo.com/168e2144ddd9ee368a05754dfd463021
shop-ajax.php(会话处理 @ 第 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 an article to the basket
*/
if (isset($_POST['size']) && isset($_POST['appearance']) && isset($_POST['quantity'])) {
    /*
     * create an new basket if not exist
    */
    if (!isset($_SESSION['basketUrl'])) {
        /*
         * get 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 the basket
        */
        $namespaces = $objShop->getNamespaces(true);
        $basketUrl = createBasket('net', $objShop, $namespaces);
        $_SESSION['basketUrl'] = $basketUrl;
        $_SESSION['namespaces'] = $namespaces;
        /*
         * get the 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 for not having the 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 to be sent to the basket resource
    */
    $data = array(
            'articleId' => intval($_POST['article']),
            'size' => intval($_POST['size']),
            'appearance' => intval($_POST['appearance']),
            'quantity' => intval($_POST['quantity']),
            'shopId' => $config['ShopId']
    );
    /*
     * add to 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, just 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 as $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 to 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 as $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 but addBasketItem
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            break;
    }
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}
?>
该脚本还有另外2个部分:一个用于将示例T恤添加到篮子中的表单和一个用于调用ajax的脚本。如果需要,可以发布它,但没有会话处理的东西。(example.php)(shop-controller.js)
更新 - 也许问题与会话无关。BasketId 丢失,但 PHPSESSID 在浏览器 Cookie 中保持不变。
在过去的3天里,我做了以下测试(用不同的计算机和浏览器进行测试):
- 清空浏览器 Cookie,然后在下午开始新会话 
- 将1个项目添加到购物篮,我写下篮子Id并检查浏览器cookie以写下PHPSESSID 
- 通常总是在午夜左右,篮子自己清空 
- PHPSESSID在我的浏览器cookie中保持不变,即使在购物篮清空之后也是如此 
- 但是,BASKETID是不一样的,下午使用的那个丢失了,一个新的被再生了。 
服务器是 CentOS 5.9 - PHP 版本 5.2.9(来自 OVH)。专用 IP 上的专用服务器。
 
					 
				 
				    		 
				    		 
				    		 
				    		