How do I check and unset/set SESSION by element? - php

I have a session var for a shopping cart that reads: 'cart_b_1_1'.
The letter in the string indicates a category, the ints represent user id & product id.
How can I check the category of an already set SESSION var to see if it matches the category of a new selection?
I am trying to make sure that if an item is added to the SESSION array and there is a var that already exists with the same category letter, then it is unset and effectively replaced with the new selection. This is to limit selections by category to one.
Thanks for the help in advance.

You should consider taking advantange of the awesomeness of what associative arrays let you do:
$_SESSION['categories'][$mycat] = array($user_id, $product_id);
That way whenever you set a new category it overrides the last one. Not sure why you need the user_id at that level, assuming the whole cart belongs to one user, my Session would look like:
array(
'user' => $user_id,
'cart' => array('catid' => 'prodid', 'catid2', 'prodid2'))
);

You should use 3 variables instead of 1.
$_SESSION['category'] = 'cart_b';
$_SESSION['user_id'] = 1;
$_SESSION['product_id'] = 1;
But just in general - you can convert string to a array with '_' separator.
$varArray = explode('_', $_SESSION['var']);

explode the session variable using _ and check the first element to find the category.
$myarray=explode("_",$_SESSION['yourvariablename']);
then you the $myarray[1] is the category so you can compare and do other stuff.
Is this what you wanted?

Related

PHP - Pulling array and splitting the strings

Not sure how to title this properly but here's the issue I am running into currently. I built a cart and checkout system and it loads all the data into a database when it finalized the order. To save some space, I stored just the item IDs originally but then I ran into the issue of if I deleted the item from the database (because it was discontinued or whatever) then it wouldn't return the info I needed. And if they ordered more then 1 item the database record would be wrong. So I stored the data like so:
Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2
OR
1:3:20.00:Flower Hat, 2:1:17.75:diamonds
The issue I have right now that I need help with is this. I need to seperate the four values into variables like $price, $item, $id, $ammount so I can display them on the order history page and I need to loop through all items on the array so I can print a row for each item with all four fields respective to that item.
I use strpos already to get the shipping info from the same database field which is formatted as METHOD:Price but since I have 3 :'s on my string I'm not sure how to go through each one. Thanks.
Here's a function
function parseItems($dbjunk){
$cart = array();
$items = explode(",",$dbjunk);
foreach($items as $i){
$chunks = explode(":", $i);
$cart[] = array(
"ItemID" => $chunks[0] ,
"Quantity" => $chunks[1] ,
"Price" => $chunks[2] ,
"name" => $chunks[3]
);
}
return $cart;
}
Example usage:
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
print_r($parsed);
See: https://3v4l.org/rBkXF
If you need variables instead of an array you can use list(), like this..
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
foreach($parsed as $p){
list($itemID, $Quantity, $Price, $name) = array_values($p);
var_dump($itemID, $Quantity, $Price, $name);
}
see: https://3v4l.org/l4vsn
You should not physically delete items from your database. Instead, put a new column named 'is_active' or something like that to indicate whether the product is active/non-deleted.
Answering your question, here is my suggestion:
$orderString = '1:3:20.00:Flower Hat, 2:1:17.75:diamonds';
$items = array();
foreach(explode(', ', $orderString) as $itemString) {
$itemData = explode(':', $itemString);
$items[] = array(
'id' => $itemData[0],
'amount' => $itemData[1],
'value' => $itemData[2],
'description' => $itemData[3]
);
}
with this code, you will obtain an array with the data of all the items in the string, no matter how much items are in the string
try something like
$data = 1:3:20.00:Flower Hat, 2:1:17.75:diamonds
list($price, $item, $uid, $id, $ammount) = explode(":", $data);
echo $user;
echo $item;
Read about First Normal Form. Basically, you want to store one value in one field. So, instead of this:
shipping = "method:price"
You want something like this:
shipping_method = "method"
shipping_price = "price"
Don't concern yourself with space -- it's essentially free nowadays.
Regarding your deleted items dilemma, your initial implementation was the way to go:
I stored just the item IDs originally
In addition to reverting to this technique, I would recommend two things:
Add a boolean field to your item table to represent if the item is currently available or not. This gives you the additional feature of being able to toggle items on/off without having to delete/insert records and change ids.
Before deleting an item, check to see if it's ever been ordered. If not, it's ok to delete. If so, instead just deactivate it.

How to delete item ID from array used as session shopping cart

I have a SESSION['cart'] with ID numbers only. I have a form passing the ID with a remove button. Once passed to my controller, I cannot figure out how to write the code that uses the ID ($_POST['id']) to delete the item from the SESSION['cart'].
I can loop through and display the array contents, but I cannot figure out how to delete based on ID passed from the form.
How do I loop through the SESSION['cart'] array to find a match with the ID passed from my delete form, and then delete that ID? I know that unset($_SESSION['cart'][X] deletes the ID at index X, but I cannot figure out how to loop through all the elements to find a match.
I have read a number of related issues in this forum but have been unable to apply any of those solutions to resolve this challenge. Any assistance is appreciated.
The way you have your values ($products = array(3,7,99,152)) isn't a very good method. Every time you want to perform an action, you have to loop through the array, you don't want that. Apart from that, how do you store quantity? Or variations like e.g. size or color?
if your structure is $array[ ID_OF_PRODUCT ], you can simply do this:
unset( $_SESSION['cart'][$_POST['id']] ); // Instant access via the key!
This should be the method to use. This allows you to create an array like this, with advanced info, but with easy access (42/63 are example id's)
$_SESSION['cart']['products'][42] = array(
'quantity' = 11,
'size' = 'large',
'color' = 'blue'
);
$_SESSION['cart']['products'][63] = array(
'quantity' = 9,
'size' = 'small',
'color' = 'red'
);
This way you can access a lot of info with the product ID, and now also see which size and color (both just examples) the user selected. You may not have need for this now, but you will further down the road :)
As you might see, you can easily do stuff with the item:
isset($_SESSION['cart'][$_POST['id']]); // check if the product exists
unset($_SESSION['cart'][$_POST['id']]); // remove the product
echo $_SESSION['cart'][$_POST['id']]['quantity']; // get the quantity.
Not a loop in the code. You should only use loops when you have to, try to somewhat avoid them because often their slow. Say you have an extreme case of 1000 items in your shop, and you need to delete no999... That'll take a noticable moment.
Here is the code to do it right:
$id = $_POST['id'];
$items = $_SESSION["cart"];
if(($key = array_search($id, $items)) !== false) {
unset($items[$key]);
}
$_SESSION["cart"] = array_values($items);
Advice
Beside item ID, you can also sve item count in SESSION array because user can add several times same item into cart. In that case your $_SESSION["card"] should be structured like:
array(
'1'=>12,//Item with ID=1 is added 12 times in shopping cart
'17'=>2,//Item with ID=17 is added 2 times in shopping cart etc.
'32'=>12,
)

Codeigniter update record

I have an update record that looks like this
$data_gallery = array(
'order' => $value
);
$this->db->where('order', $newOrder);
$this->db->update('gallery', $data_gallery);
I have say, 5 images I have reorderd. I have their old position and their new position.
But as I loop through they sometime overwrite each other.
Example:
5 images 1,2,3,4,5
I change the order 2,1,3,4,5
I update in the loop as it goes through the array of new order.
Update order = 2 where order = 1
Update order = 1 where order = 2
Obviously the second one never gets hit as order = 2 no longer exits.
I guess this more a logic question than anything else.
Any ideas how I can easily loop through and update without losing some of the data? I though maybe updating in a batch operation but didn't get very far with it.
Thanks in advance.
Use the image's ID in your WHERE clause:
$this->db->where('imageid', $imageid);
This will set the new order to each image without previously overwriting (and disappearing!) any information.
Check if you have any other fields to check for your criteria to match the exact records.
$data_gallery = array(
'order' => $value
);
$this->db->where('order', $newOrder);
//check if you have any other fields to match also image id, record id or any other ids to match
$this->db->where('second_id',$second_id);
$this->db->update('gallery', $data_gallery);

Recordset paging based on a secondary field rather than key.

Bit stuck on how to achieve this.....
I have a PHP page which shows information for one record in a table. These records include a unique key (image_id) AND a name (image_name).
In order to display the correct record, I am using a search function on a previous page which results in a URL parameter (imageinfo.php?image_id=1 etc).
My problem is that I wish to add forward and back arrows to the table to cycle through different records, BUT based on the alphabetical order of 'image_name' rather than the numerical order of 'image_id.
I'm really not sure how to achieve this, so any help would be appreciated.
Something like this: (I hope the comments will explain)
<?php
$data = array(
123 => "B",
321 => "C",
124 => "A"
);
$id = 123; // This is the current image id
asort($data); // Sort the array based on values (names)
// Advance the internal pointer until it points to the current image
while(current($data) != $data[$id])
next($data);
// TODO: Also check whether next is past end here
echo next($data); // Should be C

PHP: Session 2-Dimensional Array - Track Viewed Products

I'm trying to create an array to display the last 5 products a customer has viewed.
The array is a 2 dimensional array like below...
$RView= array(
array( ID => "1001", RefCode => "Ref_01", Name => "Name_01" ),
...
array( ID => "1005", RefCode => "Ref_05", Name => "Name_05" )
);
The array values are retrieved from the products recordset and is designed to function as follows when a customer visits a product page.
Page will check if a Session Array exists
If yes, an array variable is created from existing Session
If no, a new array is created.
Array will add the new product details.
Array will count if there are more than 5 existing products in the array.
If yes, it will remove the oldest.
If no, moves to next step.
A Session is created/updated from the revised Array.
My current effort is attached below...
Many thanks for any help.
<?php
session_start()
// Get or Create Array
IF (isset($_SESSION['sessRView'])) {
$RView = ($_SESSION['sessRView']); }
ELSE {
$RView = array(array());
}
// Append currently viewed Product to Array
array(array_unshift($RView, $row_rsPrd['PrdID'], $row_rsPrd['RefCode'], $row_rsPrd['Name']));
// Check if more than 5 products exist in Array, if so delete.
IF (sizeof($RView) > 5) {
array(array_pop($RView)); }
// Update Session for next page
$_SESSION['sessRView'] = $RView;
// Display Array
for ($row = 0; $row < 5; $row++)
{
echo "<ul>";
echo "<li><a href='?PrdID=".$RView[$row]["PrdID"]."'>".$RView[$row]["RefCode"]."</a> : ".$RView[$row]["Name"]."</li>";
echo "</ul>";
}
?>
It's more or less right - just 2 lines need to be changed.
There's no need for the extra array() around array_unshift and array_pop.
When you use array_unshift you're pushing an array of items (not the id/codes individually) - I think you mean array_unshift($RView, array($prodid,$name,...))
What if $RView doesn't have 5 elements? In that case you're accessing undefined array indices (which may or may not show an error). Change it to a foreach loop: e.g.
foreach ($Rview as $prod) echo $prod['Name']...
It should work after you make these changes. You might want to clean up the coding style a bit, though :)
EDIT: Oh, I see, when you're referencing the array in the for loop it doesn't know that the array has "ProdID" and "Name" indices. When you make an array you have to define the indexes using the => operator.
Add indexes to the array when you array_unshift:
array_unshift($RView, array("ProdID" => $row_rsProd["ProdID"], "Name"...))
If row_rsProd isn't too big, you can just tack the entire row_rsprod onto $RView.
so change array_unshift(...) to just $RView[] = $row_rsProd
This way the indexes are preserved.
Alternatively you can change the indicies in the for loop to match. Right now the array you unshift onto $RView is 0-based - $RView[0][0] is the product ID for the first product, etc.
So you can change the stuff in the foreach loop to
echo "<li>..." $prod[0] $prod[1] $prod[2]
Hope that helps!

Categories