如何在PHP 5.x中实现Method Chaining?

时间:2012-10-11 22:28:50

标签: php method-chaining

我有为PHP 5.4.x编写的以下类。这应该像我期望的那样工作吗?

class SqlBuilder {
    private $dbTable;
    private $action;
    private $data;
    private $clause;

    public function toString() {
        // $sql = generate sql string
        // [...]
        return $sql;
    }

    [...]

    public function setClause($clause) {
        $this->clause = $clause;
    }

    public function setDbTable($dbTable) {
        $this->dbTable = $dbTable;
    }   

    public function setAction($action) {
        $this->action = $action;
    }
}   
$sql = (new \dbal\SqlBuilder())
            ->setAction($this->action)
            ->setClause($this->clause)
            ->setDbTable($this->dbTable)
            ->toString();

我希望能够访问我的所有setter方法。相反,我看到以下错误:

  

致命错误:在非对象上调用成员函数toString())

这似乎有效:

$builder= new \dbal\SqlBuilder();
$builder->setAction($this->action)
$builder->setClause($this->clause)
$builder->setDbTable($this->dbTable)
$sql = $builder->toString();

但我知道这也有效:

class Foo
{
    public $a = "I'm a!";
    public $b = "I'm b!";
    public $c;

    public function getB() {
        return $this->b;
    }

    public function setC($c) {
        $this->c = $c;
        return $this;
    }

    public function getC() {
        return $this->c;
    }
}

print (new Foo)
       ->setC($_GET["c"])
       ->getC(); // I'm c!

之前我在Javascript中使用过这种语法。有没有办法让它在PHP中运行?

1 个答案:

答案 0 :(得分:5)

您要问的是方法链。为了使它按您希望的方式工作,每个方法调用都需要返回对您正在调用的对象的引用。所以,

->setAction($this->action)
// needs to return $this; so that
        ->setClause($this->clause)
// knows what to operate upon and in turn needs to return $this; so that
        ->setDbTable($this->dbTable)
// can do the same

尝试:

public function setClause($clause) {
    $this->clause = $clause;
    return $this;
}

public function setDbTable($dbTable) {
    $this->dbTable = $dbTable;
    return $this;
}   

public function setAction($action) {
    $this->action = $action;
    return $this;
}