looksgoodhoss looksgoodhoss - 3 months ago 9
PHP Question

How do I stop prevent duplicate entries to my PHP Session?

I am currently working on a project where I am storing data in PHP Sessions (PS). For various reasons, I only want to use one PS for this particular problem, which of course means that my PS will be a big, long string. To solve this issue, I have a pattern; each "block" is stored with the following format: $CategoryID;$StartingPoint;$Available;&.

To access the starting point of a particular "block", I use the following code:

function getStartPosition($CategoryID)
{
$feedItems = explode("&", $_SESSION['feedData']);
foreach($feedItems as $fI)
{
$temp = explode(";", $fI);
/*
$temp[0] = Category ID;
$temp[1] = Starting Position;
$temp[2] = Available;
*/

if($CategoryID == $temp[0])
{
$startPos = $temp[1];
}
}
return $startPos;
}


I then carry out a for-loop, with a dynamic starting value - the starting value retrieved from the previous code. At the end of each cycle within the for-loop, I increment the starting value by one with the following code:

function setStartPosition($CategoryID)
{
$feedItems = explode("&", $_SESSION["feedData"]);
foreach($feedItems as $fI)
{
$temp = explode(";", $fI);

/*$temp[0] = Category ID;
$temp[1] = Starting Position;
$temp[2] = Available;*/

if($temp[0] == $CategoryID)
{
$search = $temp[0] . ";" . $temp[1] . ";" . $temp[2] . ";&";
$replacement = $temp[0] . ";" . ($temp[1]+1) . ";" . $temp[2] . ";&";
$_SESSION["feedData"] = str_replace($search, $replacement, $_SESSION["feedData"]);
return;
}
}
}


My getters and setters work - they get, they set, they do their job. With the following string: 6;0;Y;&14;0;Y;&33;0;Y;&64;0;Y;& I can get the starting values of category 6, 14, 33 and 64 through $temp[0]. Therefore, it is safe for me to presume that my double explosion + foreach method works.

My problem, however, is initialising them. If I have a string of 6;0;Y;&14;0;Y;&33;0;Y;&64;0;Y;&, I can identify a category's starting position. If I have 6;0;Y;&6;0;Y;& then I run into problems, because once each for-loop cycle has ended, the string then becomes 6;1;0;Y;&6;0;0;Y;&... what "block" does my getter go for? That's my issue.

What I don't understand is why my code does not work. It uses the same double explosion + for-each method for getting data and thus identifying each block, but my solution does not prevent duplicate entries. Therefore, when I re-execute the code through an AJAX call, I'll have multiple duplicate entries. My code:

function addToSession($CategoryID)
{
if(isset($_SESSION["feedData"]))
{
$feedItems = explode("&", $_SESSION['feedData']);
foreach($feedItems as $fI)
{
$temp = explode(";", $fI);
/*$temp[0] = cid;
$temp[1] = sp;
$temp[2] = av;*/
$temp[1] = (int)$temp[1];
// also tried:
// if ($temp[1] == $CategoryID)
// but does not work either
if($temp[1] == 1 || $temp[1] > 1)
{
// do nothing -> already in session
}
else
{
$_SESSION["feedData"] .= $CategoryID . ";0;Y;&";
}
//return $temp[0];
}
}
else
{
$_SESSION["feedData"] .= $CategoryID . ";0;Y;&";

}
return;
}


To me, the code reads like this:
if the session feedData does not exist, then create it and add in a block.
Then, from every function call since that, check to see if a block already has a starting pointer value greater than one.
If it does, then it has already been added and therefore there is no need to add another entry.
If it does not, then add in a fresh new entry.

The code "works" on first load, because the string has unique values. However, after my AJAX call, the string is 150 characters long (normally 30ish etc) and has duplicate values.

TL;DR; I get duplicate values in my PHP Session variable, and I don't understand why as I am trying to prevent duplicate entries through my if-statement. It works on first load, but not thereafter with AJAX. Why?

Any advice, tips or thoughts will be greatly appreciated.

Thanks.

Answer

Your whole approach seems crazy, since you can store associative arrays in a session variable. You can't get duplicates because array keys are always unique.

function addToSession($CategoryID) {
    if (!isset($_SESSION['feedData'])) {
        $_SESSION['feedData'] = array();
    }
    if (isset($_SESSION['feedData'][$CategoryID]) {
        // do nothing - already in session
    } else {
        $_SESSION['feedData'][$CategoryID] = array('startingPosition' => 0, 'available' => 'Y');
    }
}

function getStartingPosition($CategoryID) {
    if (isset($_SESSION['feedData'][$CategoryID]) {
        return $_SESSION['feedData'][$CategoryID]['startingPosition'];
    } else {
        return null;
    }
}

function setStartingPosition($CategoryID) {
    if (isset($_SESSION['feedData'][$CategoryID]) {
        $_SESSION['feedData'][$CategoryID]['startingPosition']++;
    }
}