PHP: Session 2-Dimensional Array - Track Viewed Products - php

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!

Related

Need to unset a specific session array

I have set an array to a session variable using key-value pairs, but I need to unset that specific session when I click on the delete button.
This is the code that stores the session variables:
$_SESSION['product'][] = array(
'product_id' => $part_id,
'title' => $title,
'price' => $price,
'default_img' => $default_img,
'quantity' => $quantity);
And here's the code that unsets the session:
if (isset($_POST['removeItem'])) {
$prodId=$_SESSION['prodItemId'];
foreach($_SESSION['product'] as $item) {
if ($_GET["partid"] == $item['product_id']) {
unset($_SESSION["product"]);
}
The problem I'm having is that instead of just unsetting one session instance, it unsets the entire session. I've tried unset($_SESSION["product"][$item]);
You tell the code to unset the whole session, so it does.
Include the key in the foreach and unset the specific key that you need to unset.
foreach($_SESSION['product'] as $key => $item) {
if ($_GET["partid"] == $item['product_id']) {
unset($_SESSION["product"][$key]);
}
}
You could also search for the specific value and skip the whole loop thing.
if (isset($_POST['removeItem'])) {
$prodId=$_SESSION['prodItemId'];
$key = array_search($_GET["partid"], array_column($_SESSION['product'], 'product_id'));
if($key !== false) unset($_SESSION["product"][$key]);
}
Array_search searches for the GET partid and if it's found it returns the key of where it is, else it returns false.
If you have multiple array items that need to be removed the above array_search method will only remove the first.
You can however loop the array_search to get them all.
if (isset($_POST['removeItem'])) {
$prodId=$_SESSION['prodItemId'];
$prodID = array_column($_SESSION['product'], 'product_id'); // creates a flat array that can be searched
while($key = array_search($_GET["partid"], $prodID)){
unset($_SESSION["product"][$key]);
}
}
Here we search to see if there is a matching value, if there is we delete the key, then the while loop searches again.
If a new matching value is forum it's deleted, if not array_search will return false and break the while loop.
A fourth method is to almost keep the code you have as it is, but loop the array by reference with & and unset the item.
foreach($_SESSION['product'] as &$item) { // notice the &
if ($_GET["partid"] == $item['product_id']) {
unset($item); //because we used &, we can now unset $item
}
}
A fifth method is to use array_diff and array_intersect.
This method is the slowest and should not be used on larger arrays, it can be used with very little difference on smaller arrays (less than 50-100 items).
if (isset($_POST['removeItem'])) {
$prodId=$_SESSION['prodItemId'];
$_SESSION['product'] = array_intersect_key($_SESSION['product'], array_diff(array_column($_SESSION['product'], 'product_id'), $_GET["partid"]));
}
In order to explain it I need to explain it in "reverse" order from what you read it since it's nested.
I start with created a flat array with array_column.
This array only contains the productid's.
I use array_diff to return only the items that is not matching $_GET["partid"].
What we get is a flat array with only the productid's. That may sound useless, and it is, but the keys is useful.
The keys match what is in the session array.
So if we use array_intersect_key and use $_SESSION['product'] as the main array and the keys from the array_diff then the output is the items in $_SESSION['product'] that does not match $_GET["partid"].
It's complicated in the background but it's a simple on liner.

Convert multi-dimensional array into matrix-like array

I have the following array:
$array = array(
array("2018","2019"),
"Jan",
array("France","Germany")
);
I need a matrix that crosses all the elements of the array; e.g:
array(
array("2018","Jan","France"),
array("2018","Jan","Germany"),
array("2019","Jan","France"),
array("2019","Jan","Germany")
);
meaning, 2 x 2 x 1 arrays
but this can be that I have more elements that are or are not arrays then:
$array = array(
array("2018","2019"),
"Jan",
array("France","Germany"),
array("prod1","prod2","prod3"),
'Act'
);
In this case I would get 2 x 2 x 1 x 4 x 1 arrays in the end.
Any idea on how to achieve this?
Is that what you are looking for ?
$dst = array(array());
foreach ($array as $idx => $val) {
foreach ($dst as $tmp_idx => $tmp_array) {
if (is_array($val)) {
foreach ($val as $sub_idx => $sub_val) {
$dst[] = array_merge($dst[$tmp_idx], array(count($dst[$tmp_idx]) => $sub_val));
}
} else {
$dst[] = array_merge($dst[$tmp_idx], array(count($dst[$tmp_idx]) => $val));
}
unset($dst[$tmp_idx]);
}
}
I declare the array with an empty array in it.
A first foreach iterates through the main array to access all the categories, whatever their number.
A second foreach iterates through the result array.
A third foreach - or not, depending if the category contains several or a single entry - iterates through each entry of the current category and merges an array containing only that current category in the result currently iterated on (from $dst). The merge is pushed into the result array. The result stored in $dst are assumed to be temporary and will be copied and completed with each new value, making them progressively contain one entry from each category.
At the end of each iteration on $dst, the current temporary result is removed from the array since it has no purpose : if the foreach iterated on it, that means that it was incomplete.
At the end, the only entries in $dst that remain are these who weren't iterated on, meaning that every entry from each category were considered when they were created, meaning that they are complete.
I'm available for any clarification may the need arise.

Collect product variable and find the largest one in php

I am writing some code to supply the Google certified shop data which I have nearly finished. I only need to supply the ship and delivery dates. I have written code to supply this information at the product level. However when there is more than one product in an order I need to select the largest ship date.
For example;
Order has two products.
Producta with $ship_date = 2 and porductb with $ship_date = 5
I need to collect all the $ship_dates (2 and 5) and return the highest one (5).
My question is simply how do I write the php to collect all the $ship_dates correctly - should I create an array and if so how?
Put all the required variables into an array, then use max.
$ship_date1 = 2;
$ship_date2 = 5;
$shipDates = [$ship_date1, $ship_date2];
// other dates as needed
// OR, a much cleaner solution, append to the array
$shipDates = [];
$shipDates[] = 2;
$shipDates[] = 5;
//No matter how you fill up the array, this is how you get its maximum value
$maxShipDate = max($shipDates);
max actually accepts individual variables instead (eg. max($ship_date1, $ship_date2);) but the array solution is easier to maintain.
OK before my foreach product loop I added this;
$deliverydatearray = array();
which creates a new (empty) array which I called $deliverydatearray
Within my foreach product loop I added this;
$deliverydatearray[] = $delivery_datep;
which adds my product specific delivery date ($delivery_datep) to my array.
After the foreach product loop has closed I can access the variables in my array. For example just printing the contents of the array is done like this;
print_r($deliverydatearray);
which looks like this;
Array
(
[0] => 2017-01-28
[1] => 2017-01-23
)

Updating previous Session Array Laravel

I have an issue on how can I update my Previous array ?
What currently happening to my code is its just adding new session array instead of updating the declared key here's my code:
foreach ($items_updated as $key => $added)
{
if ($id == $added['item_id'])
{
$newquantity = $added['item_quantity'] - 1;
$update = array(
'item_id' => $items['item_id'],
'item_quantity' => $newquantity,
);
}
}
Session::push('items', $updated);
$items = Session::get('items', []);
foreach ($items as &$item) {
if ($item['item_id'] == $id) {
$item['item_quantity']--;
}
}
Session::set('items', $items);
If you have nested arrays inside your session array. You can use the following way to update the session: $session()->put('user.age',$age);
Example
Supppose you have following array structure inside your session
$user = [
"name" => "Joe",
"age" => 23
]
session()->put('user',$user);
//updating the age in session
session()->put('user.age',49);
if your session array is n-arrays deep then use the dot (.) followed by key names to reach to the nth value or array, like session->put('user.comments.likes',$likes)
I guess this will work for you if you are on laravel 5.0. But also note, that I haven't tested it on laravel 4.x, however, I expect the same result anyway:
//get the array of items (you will want to update) from the session variable
$old_items = \Session::get('items');
//create a new array item with the index or key of the item
//you will want to update, and make the changes you want to
//make on the old item array index.
//In this case I referred to the index or key as quantity to be
//a bit explicit
$new_item[$quantity] = $old_items[$quantity] - 1;
//merge the new array with the old one to make the necessary update
\Session::put('items',array_merge($old_items,$new_item));
You can use Session::forget('key'); to remove the previous array in session.
And use Session::push to add new items to Session.

multi dimension session array

I am using a form that is pulling data from two MySQL databases into a single dynamic page. When a user clicks add to cart I want to store that data in a multi dimensional session array to call up later when they click view cart. I am wondering how to auto increment the subset identifier(array key?) of the item when a new item is added from the add to cart form. This is what I have so far:
$newitem = array ($row_getimages['icon'],$row_getimages['title'],$row_getshoppingcart['medium'],$row_getshoppingcart['size'],$row_getshoppingcart['price'],$row_getshoppingcart['shipping']);
session_start();
if(isset($_SESSION['item'][1]))
$_SESSION['item'][1] = $_SESSION['item'][1]+ 1;
else
$_SESSION['item'][1] = 1;
Also any help for calling out the data later would be appreciated. As a user may have 1 or 20 items stored in the session I am not sure how to make sure all items would be echoed no matter how many they have added.
This is my first time at a multi dimensional array and sessions. Obviously because the image page is dynamic and purchase price is based on several factors, just using a MySQL database of available items as I have in the past is out of the question.
Thank you in advance for your time.
$newitem = array ('id' => $row_getshoppingcart['id'] , 'icon' => $row_getimages['icon'],'title' => $row_getimages['title'],'medium' => $row_getshoppingcart['medium'],'size' => $row_getshoppingcart['size'],'price' => $row_getshoppingcart['price'],'shipping' => $row_getshoppingcart['shipping']);
session_start();
$_SESSION['item'][] = $newitem;
That is all you have to do, if I understand your system correctly.
UPDATE
I updated the $newitem array to include array keys. You can reference the new item info with arrays like this:
$_SESSION['item'][(num)]['id']
Or you can loop through the results like this:
foreach ( $_SESSION['item'] AS $item )
{
echo 'id: ' . $item['id'] . '<br />';
echo 'title: ' . $item['title'];
// and so on
}
If it is not important for the numbers to be sequential, you can use:
$_SESSION['item'][] = array('a','b','c','d','e','f');
Using [] will simply add a new element to the end of the array.
However, I would probably use a product ID for the key.

Categories