可以用子链创建一个类方法链吗?

时间:2017-07-24 14:10:38

标签: php

我们说我有一个构建字段的类,我想做这样的事情:

$section = new Group('services');
$section
  ->addRepeater('showcase')
    ->setMinRows(3)
    ->addField('text')
    ->addField('image')
  ->endRepeater()
  ->endGroup();

我知道使用方法链接你可以使用$this返回父实例,但我不确定是否可以链接子类。

例如,如果addRepeater返回一个Repeater类实例,我可以在其上运行方法,但是如何获取它返回的数据并将其存储在父Group类中?

2 个答案:

答案 0 :(得分:1)

  

例如,如果addRepeater返回了一个Repeater类实例,我就可以运行了   关于那个方法,但接下来我如何获取它返回的数据并将其存储在父Group类中?

你做不到。您要么返回AB,要么不能直接混合链。根据逻辑,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相关方法需要转发器对象(在其使用的链外构造)作为参数等。

答案 1 :(得分:0)

您可以通过将Group对象传递给转发器来实现。您需要记住的是,对象始终通过引用传递,因此您在子类中执行的任何更改也将在父级中可用。

toString

结果将类似于

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);