Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 是否可以创建带有子链的类方法链?_Php - Fatal编程技术网

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"
      }
    }
  }
}

啊,我没想到!谢谢你的提示,我要好好玩玩。