链接方法和传递变量

时间:2014-04-02 11:54:54

标签: php class oop chain

假设我有这个:

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

    ....

}

我打电话的时候:

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

它无效,因为$ id不是全局的,也没有在第二个链接中设置。我是否必须手动将其传递给 - > subsection($ id)或者是否有更通用/更清晰的方式将其传递到那里?

我在这里尝试完成的是创建一个包含多个部分的(大)对象。在这些部分中,对象和/或数组都涉及到更多(链式)方法。

3 个答案:

答案 0 :(得分:3)

你可以这样做:

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

所以

$obj = (new Foo())
   ->section('one')
   ->subsection()
   ->section('two')
   ->subsection();

将产生有效的结果,如

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

请注意,以这种方式使用链接并不是一个好主意 - 它难以阅读,此外,还有实际更改数据的方法,但看起来像吸气剂一样令人困惑。

答案 1 :(得分:0)

您遇到的问题不是因为链接方法。这可能是因为您尚未声明属性$section,或者您已声明它没有属性$id

一种可能性是动态定义$section,就像你使用$id一样,即

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

class Classname {
    private $section;

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

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

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;

}

答案 2 :(得分:0)

考虑使用2个类来完成你想要的。这是一个例子

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

将输出

Array ( 

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

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