If you do not know the names of the categories before they are created, you can use the method __call to leave the dynamic creation.
An example:
class Categorias
{
protected $name;
private $prod;
public function __construct($name, $prod)
{
$this->name = $name;
$this->prod = $prod;
}
public function add($value)
{
$this->prod->categorias[$this->name][] = $value;
}
}
class Produtos
{
public $categorias = array();
public function __call($name, $arguments)
{
return (new Categorias($name, $this));
}
}
$p = new Produtos();
$p->tvs()->add("teste");
$p->pcs()->add("nome do pc");
var_dump($p->categorias);
In the code above, we create a class called categorias, which will basically be responsible for filling the class category vector produtos.
The method __call is used when some non-existent method of the object is called. That is, when categories, which you do not yet know, are called, the method __call is invoked and then we pass the call to a new instance of the class categorias.
If you know which categories can be used, the second @Wallacemaxters option would work well: Sending existing categories in the class constructor produtos and adding a check inside the __call to check if the category exists before passing on the responsibility.
Translating to the way I wrote:
class Categorias
{
protected $name;
private $prod;
public function __construct($name, $prod)
{
$this->name = $name;
$this->prod = $prod;
}
public function add($value)
{
$this->prod->categorias[$this->name][] = $value;
}
}
class Produtos
{
public $categorias = array();
public function __construct($categorias = [])
{
foreach ($categorias as $categoria) {
$this->categorias[$categoria] = [];
}
}
public function __call($name, $arguments)
{
if (!array_key_exists($name, $this->categorias)) {
// retorna erro.
}
return (new Categorias($name, $this));
}
}
$p = new Produtos(["tvs", "pcs"]);
$p->tvs()->add("teste");
$p->pcs()->add("nome do pc");
var_dump($p->categorias);
The class categorias takes the class instance as the second argument in its constructor produtos, because if you need to use some property of the product to perform the actions within the add, shall have the object available for.
We think almost the same thing, hehe. + 1
– Wallace Maxters