2

I've read this (References Explained), this stackoverflow (I say this to avoid duplicates and to show I've googled a lot before posting) and I still don't understand how to implement a very simple thing.

Here's what I want to do:

  • class Products
  • class Product

All with getter / setter.

I have a page that will construct dynamically an array of products, a group of products, then I'll create new products, and add them to that group:

<?php

$group_of_products = new Products();
$product1 = new Product();
$product1->setName("name1");
$product2 = new Product();
$product2->setName("name2");
$product3 = new Product();
$product3->setName("name3");

$group_of_products->addProduct($product1);
$group_of_products->addProduct($product2);
$group_of_products->addProduct($product3);

?>

Now here's what I want:

<?php

$group_of_products->getProduct( 0 )->setName("NewName1");
$group_of_products->getProduct( 1 )->setName("NewName2");
$group_of_products->getProduct( 2 )->setName("NewName3");

echo $product1->getName().", ";
echo $product2->getName().", ";
echo $product3->getName();

?>

And I'd like to see NewName1, NewName2, NewName3.

How should I declare the function addProduct() of the class Products to obtain such behavior?

Community
  • 1
  • 1

2 Answers2

3

You shouldn't need to pass things by reference. Here is an example that should work:

class Products
{
    private $products, $count = 0;
    function getProduct( $i)
    {
        return isset( $this->products[$i]) ? $this->products[$i] : null;
    }

    function addProduct( $product)
    {
        $this->products[$this->count++] = $product;
    }
}
nickb
  • 59,313
  • 13
  • 108
  • 143
  • I'm not sure about this. Why `$count`? Can't you just initialize the array and do `$this->products[]` instead? – netcoder Mar 14 '12 at 15:46
1

You don't need to care about references or values here (see Objects and referencesDocs), so you can just make your Products an ArrayObject (or probably an SplObjectStorage):

class Products extends ArrayObject
{
    public function __construct() {
        parent::__construct(array());
    }
    public function addProduct(Product $product) {
        $this[] = $product;
    }
    /**
     * @param $index
     * @return Product
     * @throws InvalidArgumentException
     */
    public function getProduct($index) {
        if ($this->offsetExists($index) && $this[$index] instanceof Product) {
            return $this[$index];
        }
        throw new InvalidArgumentException('No Product at index %s.', $index);
    }
}

Usage:

$group_of_products = new Products();
$product1 = new Product();
$product1->setName("name1");
$product2 = new Product();
$product2->setName("name2");
$product3 = new Product();
$product3->setName("name3");

$group_of_products->addProduct($product1);
$group_of_products->addProduct($product2);
$group_of_products->addProduct($product3);

$group_of_products->getProduct( 0 )->setName("NewName1");
$group_of_products->getProduct( 1 )->setName("NewName2");
$group_of_products->getProduct( 2 )->setName("NewName3");

echo $product1->getName().", ";
echo $product2->getName().", ";
echo $product3->getName();

Output:

NewName1, NewName2, NewName3

If you use the ArrayObject variant from above you can do as well:

$group_of_products[] = $product1;
$group_of_products[0]->setName("NewName1");

Whatever suits you.

See as well/Related: Array of objects within class in PHP.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836