Supervan Posted May 26, 2015 Share Posted May 26, 2015 How would I remove an instance of a class inside a array The content is stored inside an array. and the array inside $_SESSION ['cart'] //My Items class variables are protected. class Item { protected $id; protected $name; .... I will have have Multiple instances of $item inside the array. Cant use unset because its protected $item = new Item($result->id, $result->name); $_SESSION['cart'][] = $item; Quote Link to comment Share on other sites More sharing options...
Barand Posted May 26, 2015 Share Posted May 26, 2015 Perhaps use the id as the key inside the array $item = new Item($result->id, $result->name); $_SESSION['cart'][$result->id] = $item; then unset($_SESSION['cart'][$id]; Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 27, 2015 Author Share Posted May 27, 2015 (edited) Hi Barand, Thanks for responding. Im tried with a couple of options to get it working. Is all to do with key and I dont know how to apply it... getting... this error... Undefined property: Item::$getId //My Items class variables are protected. class Item { protected $id; protected $name; public function getId() { return $this->id; } .... Add instance and display message when item found. // Connect to db and store results in item ..... $item = new Item($result->id, $result->name); // Check product if existing in cart $cart = unserialize(serialize($_SESSION['cart'][$item->getId])); $_SESSION['cart'][$item->getId] = $item; for ($i = 0; $i < count($cart); $i++) if ($cart[$i]->getId() == $_GET['prodid']) { echo 'Item already exists'; break; } Delete product in cart... if (isset($_GET['delinfo'])) { $cart = unserialize(serialize($_SESSION['cart'][$item->getId])); unset($_SESSION['cart'][$_GET['delinfo']]); $cart = array_values($cart); $_SESSION['cart'] = $cart; } Read Session Cart and display info $cart = unserialize(serialize($_SESSION['cart'][$item->getId])); for ($i = 0; $i < count($cart); $i++) { echo "<table><tr>" . "<td>" . $cart[$i]->getId() . "</td>" . "<td>" . $cart[$i]->getName() . "</td>" . "<td><a href=\"index1.php?delinfo=" . $i . ">Delete </a></td>" . "</tr></table"; } Edited May 27, 2015 by Supervan Quote Link to comment Share on other sites More sharing options...
Barand Posted May 27, 2015 Share Posted May 27, 2015 (edited) If you stored them as I suggested, the index of each cart item in the array would be its id. To see if it already exists $item = new Item($result->id, $result->name); if (isset($_SESSION['cart'][$result->id]) { echo "Item already exists in cart"; } Unfortunalely, as soon as you do this $cart = array_values($cart); $_SESSION['cart'] = $cart; you lose the id keys that you assigned so you can't find them anymore. Edited May 27, 2015 by Barand Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 27, 2015 Author Share Posted May 27, 2015 Thanks will try will let you know if it work.. Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 27, 2015 Author Share Posted May 27, 2015 It does work.. Thx.. Getting an undefined index if i try to read the info inside the $cart.. I removed the 2 lines from the del process. $cart = array_values($cart); $_SESSION['cart'] = $cart; $cart = unserialize(serialize($_SESSION['cart'][$result->id])); for ($i = 0; $i < count($cart); $i++) { echo "<table><tr>" . "<td>" . $cart[$i]->getId() . "</td>" . "<td>" . $cart[$i]->getName() . "</td>" . "<td><a href=\"index1.php?delinfo=" . $i . ">Delete </a></td>" . "</tr></table"; } Quote Link to comment Share on other sites More sharing options...
Barand Posted May 27, 2015 Share Posted May 27, 2015 (edited) Don't use a for() loop, use foreach() foreach ($_SESSION['cart'] as $id => $item) { echo "<table><tr>" . "<td>" . $id. "</td>" . "<td>" . $item->getName() . "</td>" . "<td><a href=\"index1.php?delinfo=" . $id . ">Delete </a></td>" . "</tr></table"; } Edited May 27, 2015 by Barand Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 27, 2015 Author Share Posted May 27, 2015 Hi Barand, I dont like doing this ... Please take a look at the code... Got it to work up to a point... received funny error message .... incomplete something array... I restarted wamp and cleared my browser cache... Im getting the feeling it's not accepting session storage... My Program .... $item = new Item($result->id, $result->name, $result->description, $result->price, $result->shipping, 1); // Check product if exists in cart, add quantities together if (isset($_SESSION['cart'][$result->id])) { $_SESSION['cart'][$result->id] = $item->updateQuantity(10); } else { $_SESSION['cart'][$result->id] = $item; } } // Delete product in cart if (isset($_GET['delinfo'])) { unset($_SESSION['cart'][$_GET['delinfo']]); } //Loop thru $_SESSION['cart' and display content foreach ($_SESSION['cart'] as $id => $item) { $total = $item->getSubtotal(); echo "<table cellpadding='5' cellspacing='5' border='1'><tr> " . "<tr><th>My Shopping Cart</th></tr>" . "<td>" . $id . "</td>" . "<td>" . $item->getName() . "</td>" . "<td>" . $item->getDescription() . "</td>" . "<td>" . $item->getPrice() . "</td>" . "<td>" . $item->getShipping() . "</td>" . "<td>" . $item->getQuantity() . "</td>" . "<td>" . $item->getSubtotal() . "</td>" . "<td><a href=\"index123.php?delinfo=" . $id . ">Delete </a></td>" . "</tr>"; } echo "<tr>" . "<td colspan='6'align='right'>Total amount</td>" . "<td align='left'>" . $total . "</td>" . "</table>"; ? The full class... all should be ok with the class class Item { protected $id; protected $name; protected $description; protected $price; protected $shipping; protected $quantity; protected $subtotal; // Constructor populates the attributes: public function __construct($id, $name, $description, $price, $shipping, $quantity) { $this->id = $id; $this->name = $name; $this->description = $description; $this->price = $price; $this->shipping = $shipping; $this->quantity = $quantity; } // Method that returns the ..... public function getId() { return $this->id; } public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function getPrice() { return $this->price; } public function getShipping() { return $this->shipping; } public function getQuantity() { return $this->quantity; } public function getSubtotal() { $this->subtotal = ($this->price * $this->quantity) + $this->shipping; return $this->subtotal; } public function updateQuantity($quantity) { $this->quantity = $this->quantity + $quantity; } } Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 28, 2015 Share Posted May 28, 2015 without the actual error message and where it is occurring at in the code, there's not much chance at helping. the only two things that are apparent from the posted code are - 1) you should only be making an new instance of an item if the item doesn't exist in the cart. the $item = new item(....); belongs inside the else {...} block of code. 2) your total won't work. you are assigning the sub-total to $total. you should be adding it. Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 28, 2015 Author Share Posted May 28, 2015 Thanks for responding... The error that im getting Fatal error: Call to a member function getSubtotal() on a non-object in G:\www\oop\index123.php on line 72 line 72. $total += $item->getSubtotal(); This is what print_r session display found__PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Item [id:protected] => 1 [name:protected] => Book [description:protected] => This is a book [price:protected] => 150 [shipping:protected] => 6 [quantity:protected] => 1 [subtotal:protected] => 156 ) + The error that im getting Fatal error: Call to a member function getName() on a non-object in G:\www\oop\index123.php on line 75 line 75. . "<td>" . $item->getName() . "</td>" This is what print_r session display found__PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Item [id:protected] => 2 [name:protected] => Tea [description:protected] => Rooibos [price:protected] => 10 [shipping:protected] => 51 [quantity:protected] => 1 [subtotal:protected] => ) if (isset($_GET['prodid'])) { // create new item $parms = array(); $parms[] = array(':id', $_GET['prodid'], PDO::PARAM_INT); $productid = db::getInstance()->query("SELECT * FROM products WHERE id = :id", $parms); if ($productid->count()) { foreach ($productid->results() as $result) { $item = new Item($result->id, $result->name, $result->description, $result->price, $result->shipping, 1); } } // Check product if exists in cart, add quantities together if (isset($_SESSION['cart'][$result->id])) { echo 'found </br>'; print_r($_SESSION['cart'][$result->id]); $_SESSION['cart'][$result->id] = $item->updateQuantity(10); // for now it increment with 10 } else { echo 'not found </br>'; print_r($_SESSION['cart'][$result->id]); $_SESSION['cart'][$result->id] = $item; } } // Delete product in cart if (isset($_GET['delinfo'])) { unset($_SESSION['cart'][$_GET['delinfo']]); } //Loop thru $_SESSION['cart' and display content $total=0; echo "<table cellpadding='5' cellspacing='5' border='1'>" . "<tr><th>My Shopping Cart</th></tr>"; foreach ($_SESSION['cart'] as $id => $item) { $total += $item->getSubtotal(); echo "</tr>" . "<td>" . $id . "</td>" . "<td>" . $item->getName() . "</td>" . "<td>" . $item->getDescription() . "</td>" . "<td>" . $item->getPrice() . "</td>" . "<td>" . $item->getShipping() . "</td>" . "<td>" . $item->getQuantity() . "</td>" . "<td>" . $item->getSubtotal() . "</td>" . "<td><a href=\"index123.php?delinfo=" . $id . ">Delete </a></td>" . "</tr>"; } echo "<tr>" . "<td colspan='6'align='right'>Total amount</td>" . "<td align='left'>" . $total . "</td></tr>" . "</table>"; ?> my class class Item { protected $id; protected $name; protected $description; protected $price; protected $shipping; protected $quantity; protected $subtotal; // Constructor populates the attributes: public function __construct($id, $name, $description, $price, $shipping, $quantity) { $this->id = $id; $this->name = $name; $this->description = $description; $this->price = $price; $this->shipping = $shipping; $this->quantity = $quantity; } // Method that returns the ..... public function getId() { return $this->id; } public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function getPrice() { return $this->price; } public function getShipping() { return $this->shipping; } public function getQuantity() { return $this->quantity; } public function getSubtotal() { $this->subtotal = ($this->price * $this->quantity) + $this->shipping; return $this->subtotal; } public function updateQuantity($quantity) { $this->quantity = $this->quantity + $quantity; } } Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 28, 2015 Share Posted May 28, 2015 the following line of code is incorrect usage. it is overwriting the item in the cart with whatever value the updateQuantity() method returns - $_SESSION['cart'][$result->id] = $item->updateQuantity(10); to modify the quantity of the item in the cart, the code would look like - $_SESSION['cart'][$result->id]->updateQuantity(10); $_SESSION['cart'][$result->id] is (when you don't overwrite it) an instance of the item class. your goal would be to call the updateQuantity() method for that instance/item. you are still creating an instance of the item class in the wrong place and there's no point in looping over $productid->results() when there is at most only one matching result from the query. i think it will probably help you if you first define what a block of code is going to accomplish, then put that definition in as comments in the code. for example, the $_GET['prodid'] block of code appears to be an 'add' to cart process. what steps do you need - 1) validate the id/retrieve the corresponding product information for the id. if found, continue. if not found, output an error message. 2.a.) if the item is not in the cart, create an instance of the item class, with the submitted quantity (or a quantity of 1) and add it (assign it) to the cart. 2.b.) if the item is already in the cart, modify the quantity according to the submitted quantity. Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 28, 2015 Author Share Posted May 28, 2015 (edited) Hi Mac_gyver, Thanks for your help I selected two different products. The Array 1 can't be right.... print_r dump New product will be added.Array ( [1] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Item [id:protected] => 1 [name:protected] => Jungle Book [description:protected] => Book about jungle animals [price:protected] => 150 [shipping:protected] => 6 [quantity:protected] => 1 [subtotal:protected] => 156 ) [2] => Item Object ( [id:protected] => 2 [name:protected] => PC Format [description:protected] => Pc format no more [price:protected] => 10 [shipping:protected] => 51 [quantity:protected] => 1 [subtotal:protected] => ) ) Array ( [1] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Item [id:protected] => 1 [name:protected] => Jungle Book [description:protected] => Book about jungle animals [price:protected] => 150 [shipping:protected] => 6 [quantity:protected] => 1 [subtotal:protected] => 156 ) [2] => Item Object ( [id:protected] => 2 [name:protected] => PC Format [description:protected] => Pc format no more [price:protected] => 10 [shipping:protected] => 51 [quantity:protected] => 1 [subtotal:protected] => ) ) if (isset($_GET['prodid'])) { // Check product if exists in cart, add quantities together if (isset($_SESSION['cart'][$_GET['prodid']])) { echo 'Prodid found, quantity will be adjusted </br>'; $_SESSION['cart'][$_GET['prodid']]->updateQuantity(10); // for now it increment with 10 print_r($_SESSION['cart']); } else { // create new item... need to do... if prodid not found.... $parms = array(); $parms[] = array(':id', $_GET['prodid'], PDO::PARAM_INT); $productid = db::getInstance()->query("SELECT * FROM products WHERE id = :id", $parms); //This should only be one record.. how can i retrieve it without loop... if ($productid->count()) { foreach ($productid->results() as $result) { $item = new Item($result->id, $result->name, $result->description, $result->price, $result->shipping, 1); } } echo 'New product will be added.</br>'; $_SESSION['cart'][$_GET['prodid']] = $item; // not sure if this is correct print_r($_SESSION['cart']); } } Edited May 28, 2015 by Supervan Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 28, 2015 Share Posted May 28, 2015 (edited) i recommend clearing your $_SESSION['cart'] (it wouldn't hurt to have an 'empty cart' function in your code.) your code works for me and i suspect what you are seeing in the print_r() output is left over from what previous coding stored in the session variable. some of your code is still out of order. this - if ($productid->count()) { is the logic statement that's verifying that the submitted id was found in the database. ALL the code dependent on verifying that the id exists should be within the scope of that conditional block. Edited May 28, 2015 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 28, 2015 Author Share Posted May 28, 2015 (edited) I really appreciate all the time and afford. Thank you very much I have a 2nd php file to destroy the session. Found a duplicate print_r... that was the cause of the duplication. been struggling for the last 2 days with little sleep..Im starting to think it is the wamp server im using.. i can give you teamviewer access to my pc... i really dont know what is wrong... 1. clear session.. 2. select 1 product New product will be added.Array( [1] => Item Object ( [id:protected] => 1 [name:protected] => Jungle Book [description:protected] => Book about jungle animals [price:protected] => 150 [shipping:protected] => 6 [quantity:protected] => 1 [subtotal:protected] => ) )My Shopping Cart1 Jungle Book Book about jungle animals 150 6 1 3. select same item Prodid found, quantity will be adjusted ( ! ) Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Item" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in G:\www\oop\index123.php on line 41 4. Select a different product. New product will be added.Array( [1] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Item [id:protected] => 1 [name:protected] => Jungle Book [description:protected] => Book about jungle animals [price:protected] => 150 [shipping:protected] => 6 [quantity:protected] => 1 [subtotal:protected] => ) [2] => Item Object ( [id:protected] => 2 [name:protected] => PC Format [description:protected] => Pc format no more [price:protected] => 10 [shipping:protected] => 51 [quantity:protected] => 1 [subtotal:protected] => ) ) My Shopping Cart( ! ) Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Item" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in G:\www\oop\index123.php on line 75 <?php require_once 'core/init.php'; $product = db::getInstance()->query('SELECT * FROM products'); if ($product->count()) { echo "<table cellpadding='5' cellspacing='5' border='1'> " . "<tr><th>Products Available</th></tr>" . "<tr>" . "<th>Id</th>" . "<th>Name</th>" . "<th>Description</th> " . "<th>Price</th>" . "<th>Shipping</th>" . "<th>Quantity</th>" . "</tr>"; foreach ($product->results() as $product1) { echo "<tr>" . "<td>" . $product1->id . "</td>" . "<td>" . $product1->name . "</td>" . "<td>" . $product1->description . "</td>" . "<td>" . $product1->price . "</td>" . "<td>" . $product1->shipping . "</td>" . "<td>" . $product1->quantity . "</td>" . "<td><a href=\"index123.php?prodid=" . $product1->id . "\">Take me home</a>" . "</tr>"; } echo "</table>"; } if (isset($_GET['prodid'])) { // Check product if exists in cart, add quantities together if (isset($_SESSION['cart'][$_GET['prodid']])) { echo 'Prodid found, quantity will be adjusted </br>'; $_SESSION['cart'][$_GET['prodid']]->updateQuantity(10); // for now it increment with 10 } else { // create new item... need to do... if prodid not found.... $parms = array(); $parms[] = array(':id', $_GET['prodid'], PDO::PARAM_INT); $productid = db::getInstance()->query("SELECT * FROM products WHERE id = :id", $parms); if ($productid->count()) { foreach ($productid->results() as $result) { $item = new Item($result->id, $result->name, $result->description, $result->price, $result->shipping, 1); echo 'New product will be added.</br>'; $_SESSION['cart'][$_GET['prodid']] = $item; } } } } // Delete product in cart if (isset($_GET['delinfo'])) { unset($_SESSION['cart'][$_GET['delinfo']]); } //Loop thru $_SESSION['cart' and display content if (isset($_SESSION['cart'])) { echo '<pre>'; print_r($_SESSION['cart']); echo '</pre>'; $total = 0; echo "<table cellpadding='5' cellspacing='5' border='1'>" . "<tr><th>My Shopping Cart</th></tr>"; foreach ($_SESSION['cart'] as $id => $item) { // $total += $item->getSubtotal(); echo "</tr>" . "<td>" . $item->getId() . "</td>" . "<td>" . $item->getName() . "</td>" . "<td>" . $item->getDescription() . "</td>" . "<td>" . $item->getPrice() . "</td>" . "<td>" . $item->getShipping() . "</td>" . "<td>" . $item->getQuantity() . "</td>" // . "<td>" . $item->getSubtotal() . "</td>" . "<td><a href=\"index123.php?delinfo=" . $item->getId() . ">Delete </a></td>" . "</tr>"; } echo "<tr>" . "<td colspan='6'align='right'>Total amount</td>" . "<td align='left'>" . $total . "</td></tr>" . "</table>"; } ?> <?php # Item.php // This is a sample Item class. // This class could be extended by individual applications. class Item { protected $id; protected $name; protected $description; protected $price; protected $shipping; protected $quantity; protected $subtotal; // Constructor populates the attributes: public function __construct($id, $name, $description, $price, $shipping, $quantity) { $this->id = $id; $this->name = $name; $this->description = $description; $this->price = $price; $this->shipping = $shipping; $this->quantity = $quantity; } // Method that returns the ..... public function getId() { return $this->id; } public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function getPrice() { return $this->price; } public function getShipping() { return $this->shipping; } public function getQuantity() { return $this->quantity; } public function getSubtotal() { $this->subtotal = ($this->price * $this->quantity) + $this->shipping; return $this->subtotal; } public function updateQuantity($quantity) { $this->quantity += $quantity; } } Edited May 28, 2015 by Supervan Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 28, 2015 Share Posted May 28, 2015 (edited) based on the fatal error, i'm guessing that your item class is being included, but it's not before the session_start() statement, which it will need to be in order to restore the instances of the item class in the session data. Edited May 28, 2015 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 31, 2015 Author Share Posted May 31, 2015 based on the fatal error, i'm guessing that your item class is being included, but it's not before the session_start() statement, which it will need to be in order to restore the instances of the item class in the session data. Thanks for your input... I’m using an autoloader for the classes. The problem was intermittent. After I hardcoded the require_once it seems to be stable. I was also using a older version of wamp with apache 2.22.2 Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 31, 2015 Share Posted May 31, 2015 sounds like a path/include_path setting problem. Quote Link to comment Share on other sites More sharing options...
Supervan Posted May 31, 2015 Author Share Posted May 31, 2015 sounds like a path/include_path setting problem. thanks Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.