PHP Shopping cart class

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jorn Reed

Jorn Reed

03/04/2018 20:15:37
Quote Anchor link
Hallo,

Ik heb een shoppingcart class in elkaar gezet:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?php
class Cart implements JsonSerializable {
    private $cartItems;
  
    public function __construct($cartItems = array()) {
        $this->cartItems = $cartItems;
    }

 
    public function addItem(CartItem $cartItem) {
        $this->cartItems[] = $cartItem;
    }

  
    public function getItemByIndex($index) {
        return isset($this->cartItems[$index]) ? $this->cartItems[$index] : null;
    }

  
    public function getItemsByProductId($productId) {
        $items = array();
      
        foreach ($this->cartItems as $item) {
            if ($item->getId() === $productId) {
                $items[] = $item;
            }
        }

      
        return $items;
    }

  
    public function getItems() {
        return $this->cartItems;
    }

  
    public function setItem($index, $cartItem) {
        if (isset($this->cartItems[$index])) {
            $this->cartItems[$index] = $cartItem;
        }

        return $this;
    }

  
    public function removeItem($index) {
        unset($this->cartItems[$index]);
        return $this;
    }

  
    public function jsonSerialize() {
        $items = array();
        foreach ($this->cartItems as $item) {
            $items[] = array(
                'id' => $item->getId(),
                'quantity' => $item->getQuantity(),
                'note' => $item->getNote());
        }

      
        return $items;
    }
  
}

 
class CartItem {
    private $id;
    private $quantity;
    private $note;
 
    public function __construct($id, $quantity = 0, $note = null) {
        $this->id = $id;
        $this->quantity = $quantity;
        $this->note = $note;
    }

 
    public function getId() {
        return $this->id;
    }

 
    public function getQuantity() {
        return $this->quantity;
    }

 
    public function getNote() {
        return $this->note;
    }

 
    public function setId($id) {
        $this->id = $id;
        return $this;
    }

 
    public function setQuantity($quantity) {
        $this->quantity = $quantity;
        return $this;
    }

 
    public function setNote($note) {
        $this->note = $note;
        return $this;
    }
 
}

?>


De functies werken wel prima. Bijvoorbeeld als ik $item = $cart->setItem(1,1,'test'); doe voeg ik een product toe in de $cartItems array. Maar nu komt het lastige (in mijn mening). Ik heb een product pagina met één knop. Die knop moet een product met de desbetreffende code kunnen toevoegen in een cookie, mocht het product al bestaan dan zou het met de code de quantity moeten kunnen aanpassen. Ik loop dus best wel erg vast bij het opslaan van een product in een cookie. Zodra ik $item = $cart->addItem(); doe en dan vervolgens de cookie aanmaak met behulp van het cart object. dan krijg ik alleen het laatst toegevoegde product te zien, en niet de vorige geadde producten.
Gewijzigd op 03/04/2018 20:35:23 door Jorn Reed
 
PHP hulp

PHP hulp

26/04/2024 00:32:38
 
Ben van Velzen

Ben van Velzen

03/04/2018 21:08:14
Quote Anchor link
Ik zie het probleem niet echt. Om data te krijgen gebruik je gewoon json_encode($cart) en om weer naar de cart om te zetten decodeer je en voer je de resulterende array als constructor aan je cart class. Je zou feitelijk in je constructor willen dat je daarmee cartitems samenstelt, dus het omgekeerde van de jsonSerialize methode. Dat is alles dat je nodig hebt. Cookie afhandeling ligt hier buiten, maar is triviaal.
Gewijzigd op 03/04/2018 21:09:34 door Ben van Velzen
 
Thomas van den Heuvel

Thomas van den Heuvel

03/04/2018 21:08:45
Quote Anchor link
Is er een reden dat je geen gebruik maakt van sessies? Dan heb je het bovenstaande mogelijk ook niet nodig? Je kunt dan alles direct in $_SESSION (bijvoorbeeld in het sub-array $_SESSION['cart']) stoppen.

Als je werkt met cookies: ik mis het deel waar je een cookie uitleest, en data weer wegschrijft naar de cookie, waarschijnlijk gooi je tijdens de wegschrijfactie van alles weg.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/04/2018 00:43:54
Quote Anchor link
Verdiep je eens in sessions. Dat is beter dan cookies. Zoek je een manier om een winkelwagentje langer actief te houden dan tijdens een session dan zou je de gegevens in de database kunnen opslaan. een uniek getal dat in een cookie opgeslagen is kan je helpen om de juiste artikelen weer in de cart te plaatsen.
 
Jorn Reed

Jorn Reed

04/04/2018 14:27:35
Quote Anchor link
Normaal gesproken als ik een cookie wil voorzien van meer data doe ik iets als dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
   if(isset($_COOKIE['cart'])){
      $cart = json_decode($_COOKIE['cart']);
   }
else {
      $cart = [];
   }

   setcookie('cart', json_encode($cart), time()+3600, '/');
?>

Zo voeg ik de al eerder toegevoegde dingen toe aan de array die uiteindelijk de oude cookie overschrijft. Nu wil dat niet lukken met de class die gebruik maakt van $item = $cart->addItem();
 
Ben van Velzen

Ben van Velzen

04/04/2018 15:15:19
Quote Anchor link
Nee, omdat de encoded data geen directe representatie is van de class. Je zult hier dus een extra methode voor moeten maken als dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
public static function fromArray($data) {
  $cart = new Cart;    
  foreach ($data as $item) {
    $newItem = new CartItem($item['id'], $item['quantity'], $item['note']);
    $cart->addItem($newItem);
  }

  return $cart;
}

?>

Je kunt dan iets doen als $cart = Cart::fromArray(json_decode($_COOKIE['cart'], true));
 
Ward van der Put
Moderator

Ward van der Put

04/04/2018 16:02:10
Quote Anchor link
Het unserializen van clientdata naar een serverobject is een bekende vulnerability die kan worden misbruikt voor object injection. Zou je niet "gewoon" een unieke ID in het cookie zetten en de rest opslaan op de server?

https://www.owasp.org/index.php/PHP_Object_Injection
 
Jorn Reed

Jorn Reed

04/04/2018 17:06:04
Quote Anchor link
Ja klopt, ik sla als het ware het product id op en de quantity. de id's stop ik op de winkelwagen pagina in een query waarmee ik door de producten loop.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/04/2018 17:24:35
Quote Anchor link
Jorn Reed op 04/04/2018 17:06:04:
Ja klopt, ik sla als het ware het product id op en de quantity. de id's stop ik op de winkelwagen pagina in een query waarmee ik door de producten loop.


Wat is de reden om dat in een cookie te plaatsen?
 
Jorn Reed

Jorn Reed

04/04/2018 17:27:08
Quote Anchor link
Met $cart->addItem(new CartItem(1,1,'test')); voeg ik producten toe aan de array $cartItems. en met $cart->jsonSerialize(); foreach ik door de producten heen. De data wordt goed opgeslagen als ik alles hard coded onder elkaar zou zetten. Maar het is de bedoeling dat hij elke keer bij $_COOKIE['cart'] een product id en quantity toevoegd. en dus dat hij de huidige cookie overschrijft met de nieuwe toevoegde id's. Dus als het ware dat er nieuwe id's bij komen. Ik heb een beetje dingen als dit geprobeert:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(isset($_POST['add'])){
        if(!empty($_POST['quantity'])){
            if(!empty($_COOKIE['cart'])){
                $cart = $cart->jsonSerialize();
            }
else {
                $cart = $cart->addItem(new CartItem(1,1,'test jan'));
            }

            setcookie('cart', json_encode($cart), time()+3600, '/');
            dd($_COOKIE['cart']);
        }
    }

?>

Ik wil zeg maar eerst kijken of de cookie al gevuld is met data. Als dat zo is moet de code het nieuwe erbij toevoegen. Mocht de cookie leeg zijn/nog niet zijn aagemaakt. Dan is het de bedoeling dat hij de cookie voorziet met het zojuist toegevoegde product id.

Toevoeging op 04/04/2018 17:28:36:

Frank Nietbelangrijk op 04/04/2018 17:24:35:
Jorn Reed op 04/04/2018 17:06:04:
Ja klopt, ik sla als het ware het product id op en de quantity. de id's stop ik op de winkelwagen pagina in een query waarmee ik door de producten loop.


Wat is de reden om dat in een cookie te plaatsen?


Ik heb nog niet eerder met cookies gewerkt en wil even kijken hoe ik cookies kan overschrijven etc. Ik kan als ik een beetje verstand heb van cookies door dit project altijd nog sessions gebruiken
 
Jorn Reed

Jorn Reed

17/04/2018 22:55:40
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

    if(isset($_POST['add'])){
        if(isset($_COOKIE['cart'])){
            $items = json_decode($_COOKIE['cart'], true);
            foreach($items as $item){
                $cart->addItem(new CartItem($item['id'], $item['quantity'], 'test'));
            }
        }

        
        $itemsById = $cart->getItemsByProductId($product['id']);
        if($itemsById){
            $itemsById[0]->setQuantity($itemsById[0]->getQuantity() + 1);
        }
else {
            $cart->addItem(new CartItem($product['id'], 1, 'test'));
        }

        
        setcookie('cart', json_encode($cart), time()+3600, '/');
    }
    
?>


De bovenstaande code checkt of er een cookie: cart bestaat. Bestaat de cookie. Dan voegt hij alle producten toe aan de class die eerder in cookie zaten. Bestaat een product al, dan verandert hij de quantity van het product.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.