You can act like this way:
class Foo
{
protected $section;
private $lastUsedId = null;
public function __construct()
{
$this->section = new StdClass();
}
public function section($id)
{
// variable method name
$this->section->$id = new StdClass();
$this->lastUsedId = $id;
return $this;
}
public function subsection()
{
// $id is not available here
$this->section->{$this->lastUsedId}->subsection = array();
return $this;
}
}
so
$obj = (new Foo())
->section('one')
->subsection()
->section('two')
->subsection();
will produce valid result like
object(Foo)#1 (2) { ["section":protected]=> object(stdClass)#2 (2) { ["one"]=> object(stdClass)#3 (1) { ["subsection"]=> array(0) { } } ["two"]=> object(stdClass)#4 (1) { ["subsection"]=> array(0) { } } } ["lastUsedId":"Foo":private]=> string(3) "two" }
Note, that it isn't a good idea to use chaining like this way - it's difficult to read, and, besides, having method that actually changes data, but looks like getter, is confusing.