简体   繁体   English

链接方法和传递变量

[英]Chaining methods and passing variables

Let's say I have this: 假设我有这个:

class "classname"
{

    ....

    public function section($id)
    {
        // variable method name
        $this->section->$id = new stdClass();
        return $this;
    }

    public function subsection()
    {
        // $id is not available here
        $this->section->$id->subsection = array();
        return $this;
    }

    ....

}

When I call: 当我打电话时:

$classname->section("test")
    ->subsection();

It is not working because $id is not global nor set in the second chainlink. 它不起作用,因为$ id既不是全局的,也不是在第二个链接中设置的。 Do I have to pass it manually to ->subsection($id) or is there a more generic/cleaner way to get it there? 我是否必须手动将其传递给-> subsection($ id)还是有更通用/更干净的方法来实现?

What I try to accomplish here is to create an (big) object with multiple sections. 我在这里试图完成的工作是创建一个具有多个部分的(大)对象。 In these sections objects and/or array's so there are more (chained) methods involved. 在这些部分中,对象和/或数组是这样的,因此涉及更多(链接的)方法。

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. 请注意,以这种方式使用链接不是一个好主意-很难读取,此外,拥有一种实际上会更改数据但看上去像吸气剂的方法令人困惑。

The problem you're facing is not because of chaining methods. 您面临的问题不是由于链接方法。 It occurs either because you haven't declared the property $section or if you've declared it it has no property $id . 发生这种情况的原因可能是因为您尚未声明属性$section或者已经声明它没有属性$id

One possibility would be to define $section on the fly in the same way you're doing it with $id , ie 一种可能性是使用与$id相同的方式动态定义$section ,即

public function section($id) {
    $this->section = new stdClass();
    $this->section->id = new stdClass();
    return $this;
}

or 要么

class Classname {
    private $section;

    public function __construct() {
        $this->section = new stdClass();
    }

    public function section($id) {
        $this->section->id = new stdClass();
        return $this;
    }
}

or 要么

class Classname {

    private $section;

    public function __construct() {
        $this->section = new B();
    }

    public function section($id) {
        $this->section->id = new stdClass();
        return $this;
    }
}

class B {

    private $id;

}

Consider using 2 classes to accomplish what you want. 考虑使用2个类来完成所需的操作。 Here is an example 这是一个例子

class Document
{
    private $sections = array();

    public function addSection(Section $section)
    {
        $this->sections[] = $section;
    }

    public function getSections()
    {
        print_r($this->sections);
    }   
}

class Section {

    private $id;

    private $subsection;

    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    public function setSubsection()
    {
        $this->subsection = array();

        return $this;
    }   
}

$section1 = new Section;

$section1->setId(1)->setSubsection();

$section2 = new Section;

$section2->setId(2)->setSubsection();

$document = new Document;

$document->addSection($section1);

$document->addSection($section2);

$document->getSections();

will output 将输出

Array ( 

  [0] => Section Object ([id:protected] => 1 [subsection:protected] => Array( )) 

  [1] => Section Object ([id:protected] => 2 [subsection:protected] => Array( )))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM