Reputation:
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:
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?
Upvotes: 2
Views: 128
Reputation: 197659
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.
Upvotes: 1
Reputation: 59699
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;
}
}
Upvotes: 3