简体   繁体   中英

Sessions/foreach issue with my shopping cart

This question is actually a continuation from another question. I'd like to make sure I state all the details in this one.

I'm a relatively new programmer in the likes of Php and I have this assignment where I have to make a shopping cart

I get my product data from the database -> then I click on a product -> it goes to a page where it adds the productid, productname and price to a session with array_push and then it ends up back on the same page with where the cart is (the cart is on the same page as the productline)

cart.class.php -> this is the page where I originally receive the product data from. By using my getAllproducts(); I get all the data which I then loop through to make the 6 products appear.

<?php

class Cart
{
private $con;
private $productid;

function __construct(){
    $this->con = new PDO('mysql:host=localhost;dbname=#', '#', '#');
}

public function getProductDataById($passedId){

    $this->productid = $passedId;

    $statement = $this->con->prepare("SELECT productname, productdescription, productimage, price FROM producten WHERE productid = :productid");
    $statement->execute(array("productId" => $this->productid));
    $data = $statement->fetch();

    return($data);
}
public function getAllproducts(){

    $statement = $this->con->prepare("SELECT productid, productname, productdescription, productimage, price FROM producten");
    $statement->execute();
    $data = $statement->fetchAll();

    return($data);
}
}
?>

Next I use Cart.php to show my products. On this page I loop through the products and then when someone clicks on order (bestellen) productid, productname and price will be send to add_to_cart.php

<?php
/*errors */
error_reporting(E_ALL);
ini_set("display_errors", 1);

/*Php classes */
require_once("../classes/cart.class.php");

$products = new cart();
$data = $products->getAllproducts();

?>
<title>Side Cart</title>
</head>
<body>
<header>
    <div id="cd-cart-trigger"><a class="cd-img-replace" href="#0">Cart</a></div>

<div class="container productline">
    <div class="row">
    <?php
    foreach($data as $value){

        echo '<div class="col-md-4 productcage">';
        echo '<h2 class="product_name">'.$value["productname"].'</h2>';
        echo '<p class="price_tag">€'.$value["price"].' euro</p>';
        echo '<p class="#">'.$value["productdescription"].'...</p>';
        echo '<a href="/shoppingcart/php/add_to_cart.php?productid='.$value["productid"] . "&productname=" . $value["productname"]. "&price=" . $value["price"].'" class="btn btn_order addcart">Add to cart <span class="glyphicon glyphicon-shopping-cart"></span></a><br/><br/>';
        echo '</div>';
    }
    ?>
    </div>
</div>
<div id="cd-shadow-layer"></div>
 // Here's where the shopping cart starts 
<?php

session_start();

if(isset($_SESSION["cart"]) && count($_SESSION["cart"])> 0)

{

echo '<div id="cd-cart">';
echo '<h2>Cart</h2>';
echo '<ul class="cd-cart-items">';
echo '<li>';

 foreach($_SESSION['cart'] as $id => $value)
{
    echo 'Product Name ' . $value["productname"] . '<br/>';
    echo 'Product ID ' . $value["productid"] . '<br/>';
    echo 'Product Price ' . $value["price"] . '<br/>';
    echo '<br/>';
}

echo '</li>';
echo '</ul>';
echo '<div class="cd-cart-total">';
echo '<p>Total <span>$39.96</span></p>';
echo '</div>';

echo '<a href="#0" class="checkout-btn">Checkout</a>';
echo '<p class="cd-go-to-cart"><a href="#0">Go to cart page</a></p>';
echo '</div>';

}

?>

Then I go to add_to_cart.php

This sends the session back to cart.php where below I want to loop the products in the shopping cart

<?php
 session_start();

 if(empty($_SESSION['cart'])){
 $_SESSION['cart'] = array();
 }

 array_push($_SESSION['cart'], $_GET['productid'], $_GET['productname'], $_GET['price']);

 ?>

  <p>Het product is toegevoegd aan uw winkelwagen</p> <a href="../cart.php">Naar winkelwagen</a>

TL;DR when I try to loop through $value["productname"] my foreach returns Warning: Illegal string offset 'productname'

I have no idea how to make all of this work because I'm still quite a beginner in PHP. If someone wants to take the time to figure out my stupid mistakes it would be very amazing.

I hope I have been clear enough. I apologise for the inconvenience

 foreach($_SESSION['cart'] as $id => $value)
 {
    echo ($_SESSION[ 'cart' ][ $id ] . " " . $value); //1 1solexfiets1 solexfiets115.99 15.99
    var_dump(($_SESSION[ 'cart' ][ $id ] . " " . $value)); // string(3) "1 1" string(23) "solexfiets1 solexfiets1" string(11) "15.99 15.99"
}

I have changed the array_push to

 array_push($_SESSION['cart'], array('productid' => $_GET['productid'], 'productname' => $_GET['productname'], 'price' => $_GET['price']));

and when I print_r on cart.php I get the following back

Array ( [0] => 1 [1] => solexfiets1 [2] => 15.99 [3] => Array ( [productid] => 1 [productname] => solexfiets1 [price] => 15.99 ) )

But when I try to loop through it like this

   foreach($_SESSION['cart'] as $id => $value)
{
    echo 'Product Name ' . $value["productname"] . '<br/>';
    echo 'Product ID ' . $value["productid"] . '<br/>';
    echo 'Product Price ' . $value["price"] . '<br/>';
    echo '<br/>';
}

I still get the same error

Warning: Illegal string offset 'productname'

So is there still something I'm doing wrong? I understand now that I need to send a collection of things instead of what I did before but I still can't quite understand why its failing now

Thank you all very much for helping me! I seem to have solved the problem. I took everyone's advice and I finally have a working foreach statement. Now the products are ordered and will appear in the shopping cart

Again thanks to everyone who helped me out!

Sorry I didn't see you had a new question so i posed this as a comment to your other one.

Replace your array_push with this one and let me know if that works out for you.

array_push($_SESSION['cart'], array('productid' => $_GET['productid'], 'productname' => $_GET['productname'], 'price' => $_GET['price']));

Your problem is that you are pushing related data into an array ($_SESSION['cart']) but not maintaining that relation - think of it this way:

$_GET is an array containing a bunch of data - when you reference a specific part of that array ($_GET['productname'] for instance) you are removing it from its collection and doing something with it - with your array_push you are simply pushing stuff into another array ($_SESSION['cart']) but not maintaining the relationship - so you push a bunch of stuff into $_SESSION['cart'] over and over again, and they all kind of get lost - they no longer maintain their relation to each other.

What we do is we push an array (collection) of the things you want, so $_SESSION['cart'] now contains several collections of things, instead of just the things.

Another way to think of this is - you could just do this:

array_push($_SESSION['cart'], $_GET); 

this would have the same effect, as we are pushing the $_GET array into our other array, so the relationships are maintained - the reason you don't want to do this is because, in my example above, we create a new array with only the data we need. If we just push the whole $_GET array in there, we could end up with a bunch of other stuff we don't need (a user could put &someothervariable=aReallyReallyLongString) and then that would end up in our session as well.

<?php
    session_start();

    $_SESSION[ 'cart' ] = array();

    array_push( $_SESSION[ 'cart' ], array( 'productid' => 1, 'productname' => 'product1', 'productprice' => 15.99 ) );
    array_push( $_SESSION[ 'cart' ], array( 'productid' => 2, 'productname' => 'product2', 'productprice' => 4.99 ) );
    array_push( $_SESSION[ 'cart' ], array( 'productid' => 3, 'productname' => 'product3', 'productprice' => 17.99 ) );

    foreach( $_SESSION[ 'cart' ] AS $arr )
        echo $arr[ 'productname' ] . ' ';
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM