basic OOP shoppping cart(very basic)

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

enoc22 wrote:Ahah...I see now (sorry I'm sometimes a bit slow on the draw).
This actually isn't for any client/commercial...more of just learning php.but you are right in that i need some point to focus on accomplishing...
Excellent, no client necessary. A cart is a good way to learn OO because it is sort of objecty in the traditional sense -- with a cart and items, etc.
enoc22 wrote:For this project it would be to do the following in the most efficient way
  • ●being able to add product to the shopping cart(some product multiple times)
  • ●have it display the total of each product in the cart.
  • ●display and out of stock error for product not in the "store"
So to start with the first thing which is to add products to the cart one or more times. That leads me to a couple of questions:

- What is a "product"? I usually consider it a SKU which is a string, but it could be a primary key. We need some value that can reference back to some datasource containing product information -- typically a database table.

- What does "multiple times" mean? In my experience when some kinds of products are added to the cart each gets its own line -- even if there is already that kind of product in the cart. Other times you want adding more of the same product to just increases the quantity -- if that product is already in the cart. So, do you want just one of these or both?
(#10850)
User avatar
php_east
Forum Contributor
Posts: 453
Joined: Sun Feb 22, 2009 1:31 pm
Location: Far Far East.

Re: basic OOP shoppping cart(very basic)

Post by php_east »

arborint wrote:The important (right or wrong) point I was making is that generally stores contain carts, carts don't contain stores.
yes, but cart is the child of store. a cart cannot be the parent of a store. it doesn't make sense. hence cart extends a store. SKU extends a store too. and that will work in all php as well. and is more natural to code that way.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

php_east wrote:yes, but cart is the child of store. a cart cannot be the parent of a store. it doesn't make sense. hence cart extends a store. SKU extends a store too. and that will work in all php as well. and is more natural to code that way.
I think you have your dependencies backwards. Base classes have more basic functionality than the classes that extend them. So the most basic class in your system would be a SKU class. Next would be a Cart which would inherit the SKU functionality. And in turn a Store would use the Cart functionality, but would add additional features like organizing products into categories. Stores contain Carts; Carts contain SKUs.

And as Apollo mentions, probably inheritance is not the best way to implement this system. Composition is probably a better approach.
(#10850)
enoc22
Forum Commoner
Posts: 33
Joined: Wed Apr 01, 2009 12:45 pm

Re: basic OOP shoppping cart(very basic)

Post by enoc22 »

@arborint---Right now i was thinking of using a multidimensional array at this time like the example bellow.

Code: Select all

$catalog=array(
            733739001=>array(description=>"apples", price=>0.75 , inv=>25),
            733739002=>array(description=>"oranges", price=>0.69 , inv=>50),
            733739003=>array(description=>"pears", price=>1.00 , inv=>15),
            );
But in the future i will use a database
For adding a product mutliple times. i want it to get a total of all the product in the cart. if i enter 10 apples once then 5 apples latter. i want it to show a total of 15 apples as one line and not multiple entries.

Thanks
Oliver
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

One of the first things you can do then is to "mock" the class from which you get products. This class abstracts accessing your products. Now getting the data is hidden inside this class. Code that wants products now only cares about this interface, not where the data comes from. That is why interfaces are so important.

Here is a product class (Gateway style):

Code: Select all

class Products {
     protected $rows = array(
            733739001=>array('sku'=>733739001, 'description'=>"apples", 'price'=>0.75 , 'inv'=>25),
            733739002=>array('sku'=>733739002, 'description'=>"oranges", 'price'=>0.69 , 'inv'=>50),
            733739003=>array('sku'=>733739003, 'description'=>"pears", 'price'=>1.00 , 'inv'=>15),
            );
 
     public function find($sku) {
          if (isset($this->rows[$sku])) {
               return $this->rows[$sku];
          }
          return array();
     }
 
     public function findAll() {
          return $this->rows;
     }
}
Creating a 'mock' class is really handy when developing -- especially these supporting datasource classes. You can use this version of hte Product class while you are building your Cart class. Later you can add database code inside this class to have it fetch the data. Note that I added a 'sku' column because the database would have that column.

OK, so now you know what your products look like. And you have specified that if you add the same SKU to the Cart multiple times then there will be only one entry, but the quantity will increase. So now create a Cart class that has an addProduct($sku, $quantity) method.
(#10850)
User avatar
Apollo
Forum Regular
Posts: 794
Joined: Wed Apr 30, 2008 2:34 am

Re: basic OOP shoppping cart(very basic)

Post by Apollo »

enoc22 wrote:so at least with my shopping cart and store. they should be two seperate classes..?
Correct, I don't see any reason why one should inherit (extend) from the other. Inheritance is only meaningful when one class is a special instance or case of the other. But in this case, a cart is not a special kind of store, or vice versa.
User avatar
Apollo
Forum Regular
Posts: 794
Joined: Wed Apr 30, 2008 2:34 am

Re: basic OOP shoppping cart(very basic)

Post by Apollo »

php_east wrote:but cart is the child of store. a cart cannot be the parent of a store. it doesn't make sense. hence cart extends a store.
Why? I mean why should there be a parent / child relation at all between cart and store?
enoc22
Forum Commoner
Posts: 33
Joined: Wed Apr 01, 2009 12:45 pm

Re: basic OOP shoppping cart(very basic)

Post by enoc22 »

So basically i want to start out with a products class with a find method and maybe one or two others(add new product.ect) then build a cart class with add_product method right? ...and both of them should be separate.
let me know if i have everything strait so far

Thanks a million
Oliver
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

enoc22 wrote:So basically i want to start out with a products class with a find method and maybe one or two others(add new product.ect) then build a cart class with add_product method right? ...and both of them should be separate.
let me know if i have everything strait so far
Well there is a question of whether there is and dependency between the two classes. The only connection between the two of then is that the both hold/reference products. There are many advantages to loose coupling, so it is often best to start in that direction.

The questions are: 1) how much information about products does the cart need? and 2) where/how does it get that data? You can just pass any data needed to the cart for it to use internally. Or the cart can just know about SKUs and quantities, and get any other information from a product object.
(#10850)
enoc22
Forum Commoner
Posts: 33
Joined: Wed Apr 01, 2009 12:45 pm

Re: basic OOP shoppping cart(very basic)

Post by enoc22 »

arborint wrote:1) how much information about products does the cart need?
I would think just the SKU for now. To view other details of the product I could reference back to the product class.(which answers the other question.)
arborint wrote:2) where/how does it get that data? You can just pass any data needed to the cart for it to use internally. Or the cart can just know about SKUs and quantities, and get any other information from a product object.
Should i build my product object first and post the code then go from there?


Thanks
Oliver
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

enoc22 wrote:
arborint wrote:1) how much information about products does the cart need?
I would think just the SKU for now. To view other details of the product I could reference back to the product class.(which answers the other question.)
Which means that a product object should probably be passed to the constructor of the Cart class. The the Cart is create with the ability to get information about SKUs (e.g. price, name). So all the Cart holds is the SKU as a key to access the product, and a quantity which is is main function.
enoc22 wrote:
arborint wrote:2) where/how does it get that data? You can just pass any data needed to the cart for it to use internally. Or the cart can just know about SKUs and quantities, and get any other information from a product object.
Should i build my product object first and post the code then go from there?
Use the Product mock above. Pass it to the constructor and have a go at creating a method to add a product. Post your code and thoughts.
(#10850)
enoc22
Forum Commoner
Posts: 33
Joined: Wed Apr 01, 2009 12:45 pm

Re: basic OOP shoppping cart(very basic)

Post by enoc22 »

Back again, you guys are great!
sorry it took a while to post reply. things have been crazy

here's what i came up with for my product class. i added a little perk to the add_to method that will automatically assign a SKU.

Code: Select all

<?php
class product{
    public $product=array(
    37904=>array(d=>"bannana", c=>0.50, is=>25),
    37905=>array(d=>"apple", c=>0.76, is=>12),
    37906=>array(d=>"orange", c=>0.45, is=>20),
    37907=>array(d=>"pear", c=>1.00, is=>9),
    37908=>array(d=>"tangerine", c=>0.87, is=>30),
    37909=>array(d=>"kiwi", c=>0.94, is=>19)
    );
    function __construct(){
    }
    function view_stock() {
        echo "<pre>";
        print_r($this->product);
        echo "</pre>";
    }
    function add_to($sku, $d=null, $c=null, $is=null){
        if(!$sku==0){
            $this->product[$sku]=array(d=>$d, c=>$c, is=>$is);
        }else{
            $this->product[]=array(d=>$d, c=>$c, is=>$is);
        }
    }
}
/*to add product to product class use $good->add_to 
$sku=product sku, $d=description, $c=cost, $is=In Stock 
if sku is 0 then this function will automaticly asign the next sku in numerical order*/
$good= new product();
$good->view_stock();
echo $good->product[37904]["is"];
$good->add_to(0, "lime", 0.69, 12);
$good->view_stock();
?>
Let me know what you think and any improvements i could make

Thanks
Oliver
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: basic OOP shoppping cart(very basic)

Post by Christopher »

enoc22 wrote:here's what i came up with for my product class. i added a little perk to the add_to method that will automatically assign a SKU.
Let me know what you think and any improvements i could make
Honestly we don't care that much about the Product class at this point. It would probably be a Gateway style class which means that you would probably deal with a database table and work with rows of data from the database. PHP's associative arrays are fine for that.

I have a few comments. This first one is about what is called Separation of Concerns. This class is really about managing product data, not about displaying product data. So, even for debug, you really done want to mix different "concerns" within a class. So this method should go in a separate ProductView class.

Code: Select all

    function view_stock() {
        echo "<pre>";
        print_r($this->product);
        echo "</pre>";
    }
 
You can have explicit parameters here if you want to, but my experience with this kind of data is that you get a row from the database and then you put a row back to the database. So you might want to think about just accepting an assoc array for this method. Second, I don't think you want to accept products that don't have SKUs because that is the key that we use to find products. So you should enforce having all nencessary data here or it does not get added.

Code: Select all

    function add_to($sku, $d=null, $c=null, $is=null){
        if(!$sku==0){
            $this->product[$sku]=array(d=>$d, c=>$c, is=>$is);
        }else{
            $this->product[]=array(d=>$d, c=>$c, is=>$is);
        }
    }
 
Generally you want to access your data via methods rather than dig into the structure of the data. That way you are free to change the structure internally without effecting application code, so instead of this:

Code: Select all

echo $good->product[37904]["is"];
 
So this:

Code: Select all

echo $good->inStock(37904);
 
As discussed, it would probably be better to find and then update assoc arrays. So instead of this:

Code: Select all

$good->add_to(0, "lime", 0.69, 12);
Do this:

Code: Select all

$product = array('sku'->'37904', 'description'=>"lime", 'price'->0.69, 'inventory'->12);
$good->add($product);
You still need to get to the Cart. maybe start with something like this:

Code: Select all

class Cart {
    protected $items = array();
    protected $product;
 
    /*
     * Cart requires a product object be passed to constructor so Cart can access product data
     */
    public function __construct($product) {
        $this->product = $product;
    }
 
    public function add($sku, $quantity) {
        // ?
    }
}
(#10850)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: basic OOP shoppping cart(very basic)

Post by Benjamin »

Just to add to what arborint said, and I'm pretty sure he will agree, the following code is not correct if you are adhering to MVC.

Code: Select all

 
 function view_stock() {
        echo "<pre>";
        print_r($this->product);
        echo "</pre>";
    }
 
More correct would be to create a method that would get the stock. You can then call this from your view and display it as required..

Code: Select all

 
function get_stock() {
    return $this->product;
}
 
I am sorry if this post is ignorant of what has already been said. I have not read every post.
Post Reply