Jump to content

How would I remove an instance of a class inside a array


Supervan

Recommended Posts

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;
Link to comment
Share on other sites

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 by Supervan
Link to comment
Share on other sites

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 by Barand
Link to comment
Share on other sites

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";
}
Link to comment
Share on other sites

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 by Barand
Link to comment
Share on other sites

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;
    }
}
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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;
    }
}

Link to comment
Share on other sites

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. 

Link to comment
Share on other sites

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 by Supervan
Link to comment
Share on other sites

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 by mac_gyver
Link to comment
Share on other sites

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 Cart
1 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 by Supervan
Link to comment
Share on other sites

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 by mac_gyver
Link to comment
Share on other sites

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

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.