$Product class can't generate multiple new instances.

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

$Product class can't generate multiple new instances.

Post by eliezer »

Hi, I'm kinda new into classes and object oriented programming, right now I want to set up a Class that allows me to generate kinda like a product list.

It's more or less like a shopping cart, and I'm having trouble finding a way to send multiple products to the class so it generates multiple instances with it's own values.

I tought about managing each product as arrays. But I have trouble implementing that into the class and the way to input the information.

Basically, I need my class to list me "N" number of products with it's description and cost.

The code below works for a single instance. I think I should give any "new Product" a array indexing or something like:
$n1 = new Product('Cost' => '30', 'Description' => 'My first Product', 'Amount' => '2');
and then I shall define class variable attributes as arrays. But can't manage to do so. I need help. :cry:

Code: Select all

<?PHP
class Producto
{
 //i think i shall declare this variables as $cantidad=array(); $precio=array(); and so on...
private $cantidad;
private $precio; 
private $descripcion;

function __construct($cantidad,$precio,$descripcion)
{
//here i believe i shall use a foreach function and set $this->cantidad[] as $cantidad but tryied so and did not work
$this->cantidad = $cantidad;
$this->precio = $precio;
$this->descripcion = $descripcion;
}
	function getCuantos()
	{
	return $this->cantidad;
	}
	function getPrecio()
	{
	return $this->precio;
	}
	function getDescripcion()
	{
	return $this->descripcion;
	}
}

// what i want is to do not have to type all this code below for EACH product that i want to add.
// there's gotta be a better method.
$creaProducto = new Producto('2','30','lo que sea');
echo $creaProducto->getCuantos()."<BR>";
echo $creaProducto->getPrecio()."<BR>";
echo $creaProducto->getDescripcion()."<BR>";

?>
If help available, I'd like to see the code commented or something. Because I learn faster with practical examples then theory and the situation here is that I do not know how to manage arrays very well, but still have the urge to finish this cause it's kinda like my test to get a vacancy in a small enterprise.

Thanks a lot.
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

So I managed to insert all array values in the class but it's not printing correctly, error seems to be on the foreach function.

HELP PLEASE! ):

Code: Select all

<?PHP
class Producto {

     var $productos;

     function anade_productos($producto, $cantidad, $precio)
     {
	$this->productos[$producto]=$cantidad;
     }

     function imprime_productos()
     {
	return $this->productos;
     }

}

$cart = new Producto;

$cart->anade_productos("Apples", 5, 13);
$cart->anade_productos("Oranges", 15, 26);
$cart->anade_productos("Peaches", 17, 39);

$productos_facturados = $cart->imprime_productos();

foreach($productos_facturados as $key => $value)
{
     echo "Producto: $key; Cantidad: $value, Costo: $precio<hr>";
} 
?>

Code: Select all

Prints:

Producto: Apples; Cantidad: 5, Costo: 
________________________________________________
Producto: Oranges; Cantidad: 15, Costo: 
________________________________________________
Producto: Peaches; Cantidad: 17, Costo:
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

My instinct would be to generate each product as it's own object, adding them to either a cart object or an array in $_SESSION

Does that make more sense?
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

Okay Huggins, I did the var_dump and now I get you. I'm generating only one object.
Is there any other way than session to generate multiple objects?

Code: Select all

<?PHP
class Producto {
     var $producto;
     var $cantidad;
     var $precio;

     function anade_productos($producto, $cantidad, $precio)
     {
	$this->producto[$producto]=$producto;
	$this->cantidad[$cantidad]=$cantidad;
	$this->precio[$precio]=$precio;
     }
     function imprime_productos()
     {
	echo $this->producto[$producto];
	echo $this->cantidad[$cantidad];
	echo $this->precio[$precio];
     }
}

$cart = new Producto;
$cart->anade_productos("Apples", 5, 13);
$cart->anade_productos("Oranges", 15, 26);
$cart->anade_productos("Peaches", 17, 39);

$productos_facturados = $cart->imprime_productos();

echo $productos_facturados;
var_dump($cart);
?>

Code: Select all

var_dump($cart)...

object(Producto)#1 (3) { ["producto"]=>  array(3) { ["Apples"]=>  string(6) "Apples" ["Oranges"]=>  string(7) "Oranges" ["Peaches"]=>  string(7) "Peaches" } ["cantidad"]=>  array(3) { [5]=>  int(5) [15]=>  int(15) [17]=>  int(17) } ["precio"]=>  array(3) { [13]=>  int(13) [26]=>  int(26) [39]=>  int(39) } }
So it seems like I do know I have three arrays of Product and all their values.
I still don't know how to tear appart each array set on product.
I mean, it seems like I could get the full product list as one single object. That'd be good... if I'd knew how to do it.
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

Well, I'm not that good at classes. But I think I've found a way to solve this issue.

I'll picture a MySQL table for Products as a Class named Products with such attributes or properties as UnitaryPrice,Description,Discount,UniqueID.

Then, I'll only need to add as methods for that clase a setter and a getter.

Then, with a Class named ProductWriter I'll have as properties:
UniqueID and Amount.

For this Class I'll set as methods a setter, getter, writter.
Through the class ProductWriter->setUniqueID() I shall be able to call an instance of the class Product->getUniqueID().

So far am I right???
______________________
class ProductWritter
- Id int
- Amount int
+++++++++++++
setId();
getId();
setAmount();
getAmount();
______________________
class Product
- Id int
- Name str
- Price int
++++++++++++++
setId();
getId();
setName();
getName();
setPrice();
getPrice();
______________________
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I can't see how this will work at all without sessions.
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

Well, the guy just wants an output for the data.
It doesn't really have to save information or anything yet.
That's why I'm thinking of finding a method through arrays. I'm pretty sure there gotta be various methods to do this without Sessions.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

All you are looking for is a way to set information into the class then dump that information back to the client right? Without the need for state management or anything else, right? If so, all you need is a few setter methods and a (few) getter method(s). It shouldn't be that complicated.
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

Everah wrote:All you are looking for is a way to set information into the class then dump that information back to the client right? Without the need for state management or anything else, right? If so, all you need is a few setter methods and a (few) getter method(s). It shouldn't be that complicated.
You totally got it man.

Now, I tought of sending one array for each setter method. Three setter methods shall make it, lets say I send $product to it's method, same with $price and $description:

Code: Select all

$product = array('$product1', '$product2');
$price = array('price', 'priceprice');
$description = array('nice kitchenette', 'dildo mp3');
And then use an array_merge or something like that to index products like this:

Code: Select all

$product1-$price - nicekitchenette
$product2 - $priceprice - dildo mp3
But still I haven't been able to do it, been having this thing in my head in my head for the last two weeks. Two weeks ago I had no idea of what was UML and DOM, so you can go and figure out how stucked I am.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

I think your first step is going to be figuring out how to relate the information. You only need one data variable in the class (which should be an array) that would ideally be keyed on a product ID. Then as items are added to the object, the array would increment the needed quantities for the given id (or if you have to, product name). When you need the data back, dump it based on id (or product name).

Code: Select all

<?php
class Products {
  /**
   * Array of products in the object
   */
  protected $products = array();

  // Constructor
  public function __construct($product = array()) {
    $this->register($product);
  }

  // Register a product to the object
  public function register($product = array()) {
    // Only add the product into the object if it is not empty
    if (! empty($product) && isset($product['name']) {
      // If there is already an existing product in the object add to it
      if (array_key_exists($product['name'], $this->products)) {
        // There is already a product entry for this product in the object
        if (isset($product['quantity'])) {
          // Did we pass a quantity?
          $this->products[$product['name']]['quantity'] += $product['quantity'];
        } else {
          // Set a default of 1 if the quantity was not passed
          $this->products[$product['name']]['quantity'] = 1;
        }
      } else {
        // There was no product in here so we need to add it with a quantity and description
        if (isset($product['quantity'])) {
          // Did we pass a quantity?
          $this->products[$product['name']]['quantity'] = $product['quantity'];
        } else {
          // Set a default of 1 if the quantity was not passed
          $this->products[$product['name']]['quantity'] = 1;
        }
        
        // Handle a description
        if (isset($product['description'])) {
          $this->products[$product['name']]['description'] = $product['description'];
        } else {
          // Enter your own non-provided description code here          
        }
      }
    }
  }
  
  // Get a single product
  public function getProduct($name) {
    return $this->products[$name];
  }
  
  // Get all products
  public function getProducts() {
    return $this->products;
  }
}

// test it
$product = array(
  'name' => 'Test 1',
  'quantity' => 5,
  'description' => 'Test Product'
);

$p = new Product($product);
echo '<pre>', print_r($p->getProducts(), true), '</pre>';

// Test an add of something existing
$p->register($product);
echo '<pre>', print_r($p->getProducts(), true), '</pre>';

// Add something new
$product = array(
  'name' => 'Test 2',
  'quantity' => 20,
  'description' => 'Test Product again'
);

// Test an add of something new
$p->register($product);
echo '<pre>', print_r($p->getProducts(), true), '</pre>';
?>
Untested, and it can be extended greatly I am sure. But it might get you on the right track.
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

[quote="Everah"]I think your first step is going to be figuring out how to relate the information. You only need one data variable in the class (which should be an array) that would ideally be keyed on a product ID. Then as items are added to the object, the array would increment the needed quantities for the given id (or if you have to, product name). When you need the data back, dump it based on id (or product name).

Well, your signature states plain truth! You are incredibly friendly and helpful, yet, there's something wrong with the code. I'll keep trying to debug that and continoue analyzing it, I should be able to handle this error, guess so! lol

Code: Select all

Parse error: syntax error, unexpected '{' in /opt/lampp/htdocs/cazares/index.php on line 16
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

Everah wrote:I think your first step is going to be figuring out how to relate the information. You only need one data variable in the class (which should be an array) that would ideally be keyed on a product ID. Then as items are added to the object, the array would increment the needed quantities for the given id (or if you have to, product name). When you need the data back, dump it based on id (or product name).
Well, your signature states plain truth! You are incredibly friendly and helpful, yet, there's something wrong with the code. I'll keep trying to debug that by analyzing it, I should be able to handle this error, guess so! lol

Code: Select all

Parse error: syntax error, unexpected '{' in /opt/lampp/htdocs/cazares/index.php on line 16
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

I've actually written something very similar, which is essentially the same as Everah's except I abstracted the product itself to it's own object. Anyways, here it is..

Code: Select all

<?php

class Product_Item 
{
	protected $_name;
	protected $_quantity;
	protected $_cost;
	protected $_description;
	
	public function __construct($name, $quantity = 0, $cost = 0, $description = '') {
		$this->setName($name);
		$this->setQuantity($quantity);
		$this->setCost($cost);
		$this->setDescription($description);
	}
	
	public function setName($name) {
		$this->_name = $name;
	}
	
	public function getName() {
		return $this->_name;
	}
	
	public function setQuantity($quantity) {
		$this->_quantity = intval($quantity);
	}
	
	public function getQuantity() {
		return $this->_quantity;
	}	
	
	public function setCost($cost) {	
		$this->_cost = floatval($cost);
	}
	
	public function getCost() {
		return $this->_cost;
	}
	
	public function setDescription($description) {
		$this->_description = $description;
	}
	
	public function getDescription() {
		return $this->_description;
	}
}

class Product_Shelf
{
	protected $_products = array();

	public function addProduct(Product_Item $product) {
		$name = $product->getName();
		//product already exists, so lets increment the quantity only
		if (isset($this->_products[$name])) {
			$this->_products[$name]->setQuantity(($this->_products[$name]->getQuantity() + $product->getQuantity()));
		}
		//add the product 
		else {		
			$this->_products[$name] = $product;
		}
	}
	
	public function getProducts() {
		return $this->_products;
	}
}

$shelf = new Product_Shelf();
$shelf->addProduct(new Product_Item('milk', 50, 9.99, 'not expired'));
//we can add only quantity to an item that already exists on the shelf
$shelf->addProduct(new Product_Item('milk', 50));  
$shelf->addProduct(new Product_Item('bread', 46, 4.99, 'fresh wholegrain bread')); 

foreach ($shelf->getProducts() as $product) {
	echo 'Name: '. $product->getName() .'<br>';
	echo 'Quantity: '. $product->getQuantity() .'<br>';
	echo 'Cost: '. $product->getCost() .'<br>';
	echo 'Description: '. $product->getDescription() .'<hr>'; 
}

?>
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Forgot to close a parenthesis on a conditional. Try this:

Code: Select all

<?php
class Products {
  /**
   * Array of products in the object
   */
  protected $products = array();

  // Constructor
  public function __construct($product = array()) {
    $this->register($product);
  }

  // Register a product to the object
  public function register($product = array()) {
    // Only add the product into the object if it is not empty
    if (! empty($product) && isset($product['name'])) {
      // If there is already an existing product in the object add to it
      if (array_key_exists($product['name'], $this->products)) {
        // There is already a product entry for this product in the object
        if (isset($product['quantity'])) {
          // Did we pass a quantity?
          $this->products[$product['name']]['quantity'] += $product['quantity'];
        } else {
          // Set a default of 1 if the quantity was not passed
          $this->products[$product['name']]['quantity'] = 1;
        }
      } else {
        // There was no product in here so we need to add it with a quantity and description
        if (isset($product['quantity'])) {
          // Did we pass a quantity?
          $this->products[$product['name']]['quantity'] = $product['quantity'];
        } else {
          // Set a default of 1 if the quantity was not passed
          $this->products[$product['name']]['quantity'] = 1;
        }
        
        // Handle a description
        if (isset($product['description'])) {
          $this->products[$product['name']]['description'] = $product['description'];
        } else {
          // Enter your own non-provided description code here          
        }
      }
    }
  }
  
  // Get a single product
  public function getProduct($name) {
    return $this->products[$name];
  }
  
  // Get all products
  public function getProducts() {
    return $this->products;
  }
}

// test it
$product = array(
  'name' => 'Test 1',
  'quantity' => 5,
  'description' => 'Test Product'
);

$p = new Product($product);
echo '<pre>', print_r($p->getProducts(), true), '</pre>';
?>
eliezer
Forum Newbie
Posts: 11
Joined: Sat Nov 03, 2007 11:45 am

Post by eliezer »

You guys were amazing!!!

Cannot thank you enough for this.

You know, as personal information, I hate this Datamine inc. manager 'cause he kept telling me 'you're wrong' at my code but didn't gave any info out to work out my issues.
When I see written code it is easier for me to understand. Maybe for everyone. But that guy seems to be very selfish and jealous with knowledge.

Once again, thanks a lot to you both!!!
Post Reply