Php 是否可以创建带有子链的类方法链?
假设我有一个构建字段的类,我想这样做:Php 是否可以创建带有子链的类方法链?,php,Php,假设我有一个构建字段的类,我想这样做: $section = new Group('services'); $section ->addRepeater('showcase') ->setMinRows(3) ->addField('text') ->addField('image') ->endRepeater() ->endGroup(); 我知道使用方法链接可以使用$this返回父实例,但我不确定是否可以链接子类 例
$section = new Group('services');
$section
->addRepeater('showcase')
->setMinRows(3)
->addField('text')
->addField('image')
->endRepeater()
->endGroup();
我知道使用方法链接可以使用$this
返回父实例,但我不确定是否可以链接子类
例如,如果addRepeater
返回了一个Repeater类实例,我可以在该实例上运行方法,但是如何获取它返回的数据并将其存储在父组
类中呢
例如,如果addRepeater返回一个Repeater类实例,我可以运行
方法,但如何获取它返回的数据并将其存储在父组类中
你不能。您可以返回A
或B
,因此不能直接混合链。根据逻辑,addRepeater()
不应返回Repeater
,而应返回Group
,如果addField()
是Repeater
的方法,则需要将其链接到外部:
$repeater = (new Repeater('showcase'))
->setMinRows(3)
->addField('text')
->addField('image')
->endRepeater();
$section = new Group('services');
$section
->addRepeater($repeater)
->endGroup();
或者使
Repeater
相关方法需要Repeater对象(在使用它的链之外构造)作为参数等。您可以通过将Group对象传递给Repeater来实现这一点。您需要记住的是,对象总是通过引用传递的,因此您在子类中所做的任何更改也将在父类中可用
class Repeater
{
private $name;
private $group;
private $fields = [];
public function __construct($name, Group $group)
{
$this->name = $name;
$this->group = $group;
}
public function addField($field)
{
$this->fields[] = $field;
return $this;
}
public function endRepeater()
{
return $this->group;
}
}
class Group
{
private $name;
private $repeaters = [];
public function __construct($name)
{
$this->name = $name;
}
public function addRepeater($name)
{
$repeater = new Repeater($name, $this);
$this->repeaters[] = $repeater;
return $repeater;
}
public function endGroup()
{
echo 'group ended';
}
}
$section = new Group('services');
$section
->addRepeater('showcase')
->addField('test')
->addField('test 1')
->endRepeater()
->addRepeater('another repeater')
->addField('something')
->addField('something else')
->endRepeater()
->endGroup();
var_dump($section);
结果会是这样
object(Group)#1 (2) {
["name":"Group":private]=>
string(8) "services"
["repeaters":"Group":private]=>
array(2) {
[0]=>
object(Repeater)#2 (3) {
["name":"Repeater":private]=>
string(8) "showcase"
["group":"Repeater":private]=>
*RECURSION*
["fields":"Repeater":private]=>
array(2) {
[0]=>
string(4) "test"
[1]=>
string(6) "test 1"
}
}
[1]=>
object(Repeater)#3 (3) {
["name":"Repeater":private]=>
string(16) "another repeater"
["group":"Repeater":private]=>
*RECURSION*
["fields":"Repeater":private]=>
array(2) {
[0]=>
string(9) "something"
[1]=>
string(14) "something else"
}
}
}
}
啊,我没想到!谢谢你的提示,我要好好玩玩。