programing

php 세션이 무작위로 손실되어 왜인지 이해할 수 없습니다.

oldcodes 2023. 9. 26. 22:32
반응형

php 세션이 무작위로 손실되어 왜인지 이해할 수 없습니다.

프로그래머에게 돈을 주고 상점 바구니 스크립트를 만들어서 스프레드셔츠 API로 작업하게 했습니다.바구니가 자꾸 비는 것만 빼면 모든 것이 완벽하게 작동합니다.어느 가 또 다를 하는 것 .BasketId.

뭔가 특별한 이유가 있는지 찾아보려고 했지만 아무 성과가 없었습니다버그를 재현할 수가 없습니다.아무 이유 없이 그냥 무작위로 일어나는 일입니다.브라우저를 닫거나 아파치를 재설정하거나 웹 서버 전체를 재설정해도 세션 손실이 발생하지 않습니다.

동일한 도메인에서 쿠키로 작동하는 스크립트가 두 개 있는데 문제가 없습니다(하나는 관리자 로그인 세션용 쿠키이고 다른 하나는 사용자가 마지막으로 본 문서를 상점에 저장하는 것입니다).

모든 해결책들을 하지 못했습니다: . php.ini 설정을 해 ini하고,했습니다를 했습니다.htaccessway, ...

다음은 제 phpinfo의 "sessions" 부분입니다. 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 에 (example.php)(shop-controller.js)할 수 하는 것은 필요하면 게시할 수 있지만 세션 처리는 없습니다.

update - 이 문제는 세션과 관련이 없을 수 있습니다.BasketId는 손실되었지만 PHPSESSID는 브라우저 쿠키에서 그대로 유지됩니다.

지난 3일 동안 다음과 같은 테스트를 수행했습니다(다른 컴퓨터 및 브라우저로 테스트).

  • 브라우저 쿠키를 비운 다음 오후 동안 새 세션을 시작합니다.

  • 바스켓에 아이템 1개를 추가하고, BasketId를 적고 브라우저 쿠키를 확인하여 PHPSESSID를 적습니다.

  • 보통 자정쯤이면 바구니가 비게 됩니다.

  • PHPESSID는 바스켓 자체를 비운 후에도 브라우저 쿠키에서 그대로 유지됩니다.

  • 그러나 BASKETID가 동일하지 않아 오후에 사용하던 것이 분실되고 새로운 것이 재생성됩니다.

서버는 CentOS 5.9 - PHP 버전 5.2.9 (OVH에서)입니다.전용 IP 상의 전용 서버.

먼저 문제가 세션의 가비지 컬렉션에 있는지 코드 내의 논리적 오류인지 확인해야 합니다.이를 위해 다음을 수행할 수 있습니다.

// Add this right after session_start()
if (!isset($_SESSION['mySessionCheck'])) {
    $_SESSION['mySessionCheck'] = "This session (" . session_id() . ") started " . date("Y-m-d H:i:s");
}

// For HTML pages, add this:
echo '<!-- ' . $_SESSION['mySessionCheck'] . ' -->';

// For AJAX pages, add "mySessionCheck" to the JSON response:
echo json_encode(
    array(
        "c" => array(
            "u" => $_SESSION['checkoutUrl'],
            "q" => $basketData[0],
            "l" => $basketData[1]
        ),
        "mySessionCheck" => $_SESSION['mySessionCheck']
    )
);

이 메시지가 바스켓이 비는 동시에 바뀌면 PHP 세션의 문제임을 확실히 알 수 있습니다.

이 경우 다음과 같은 몇 가지 방법을 시도해 볼 수 있습니다.

1) 당신은 하고 있습니다.

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

그러나 PHP.net 문서의 사용자 기여 노트에 따르면 다음과 같습니다.

PHP의 Session Control은 사용 시 세션 수명 시간을 올바르게 처리하지 못합니다.session_set_cookie_params().

그래서 당신은 사용해 볼 수 있습니다.setcookie()대신:

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

댓글에 지적되어 있는 4년 된 노트임에도 불구하고 테스트를 해보니 여전히 발생합니다(PHP 5.5.7, Windows Server 2008, IIS/7.5에 있습니다).오직.setcookie()만료 날짜를 변경하기 위해 HTTP 헤더를 만들었습니다(예: 설정).$lifetime600)로:

Set-Cookie: PHPSESSID=(the id); expires=Mon, 22-Jun-2015 15:03:17 GMT; Max-Age=600

2) 데비안 서버나 파생 모델을 사용하는 경우에는 크론 작업을 사용하여 PHP 세션을 삭제하므로 다음을 시도해 볼 수 있습니다.

3) 세션을 지우는 과정이 있는지 확인하려면 세션 파일이 저장된 디렉토리에 워치를 설치하면 됩니다(실제 경로는 서버마다 다르므로 사용자의 위치를 확인하는 데 사용).저는 서버 관리자는 아니지만, 파일을 변경한 사용자를 기록해 두십시오. 누가 변경했는지 기록해야 합니다.

4) 서버 구성에 대한 액세스 권한이 없거나 서버 구성에 의존하고 싶지 않은 경우(호스트를 전환하는 경우 좋음), 자신의 세션 핸들러를 구현할 수 있습니다.페드로 기메노의 이 를 확인해 보세요.

당신은 오직. @session_start();모든 대본의 맨 위에.

A는 당신의 ajax 스크립트의 맨 위에도 입력합니다.

예: 다음과 같습니다.

@session_start();
// you may use session script here or header file
include("header.php");
//some code. you may use session script here or header file

include("main.php");
//-----------next code

오래된 게시물이라도 누군가가 이 문제를 경험할 경우 php.ini session.gc_maxlifeetime 또는 print ini_get('session.gc_maxlifeetime')을 여기에 게시합니다. php 스크립트 또는 php.ini에 설정해야 합니다. 내 php 버전의 기본값은 1440초이며 1개월로 변경했습니다. 내 경우에는 충분합니다.또한 시작 세션 후 쿠키를 설정할 수 있습니다(session_name (),session_id (), 타임 () + $sessionLifetime, ", ", ", ", " false, true);도움이 되었으면 좋겠습니다.

내 경우엔 내가 대신했습니다session_destroy();와 함께session_unset();문제가 해결되었습니다.

언급URL : https://stackoverflow.com/questions/30931170/php-session-is-randomly-lost-and-cant-understand-why

반응형