具有不同返回值的函数链接


Function chaining with different return values?

是否可以让一个方法根据上下文返回不同的值(返回值的使用方式)?例如,当一个方法与箭头运算符一起使用来调用另一个方法(即链接方法调用)时,它是否会返回$this,但当返回值没有以这种方式使用时,它会返回标量?

案例1:

$result = $test->doSomething1(); // returns 4
// $result returns 4

案例2:

$result = $test->doSomething1()->doSomething2();
// doSomething1() returns $this
// doSomething2() returns 8

有没有这样的行为?

如果我正确理解这个问题,您希望方法(doSomething1)根据调用链的其他部分返回一个值。不幸的是,你绝对不可能做到这一点。

"所有"语言之间共享的通用编程范式(方法、运算符等在语法上下文中的工作方式)规定,必须先计算出表达式$this->doSomething1()的结果,然后才能考虑对其调用->doSomething2()的结果。静态类型语言和动态类型语言以不同的方式实现这一点,但共同的因素是,表达式$this->doSomething1()必须独立于后面的内容或不后面的内容来考虑。

简而言之:在这两种情况下,$this->doSomething1()都必须返回特定类型的值。在PHP中,不可能有一种类型的值在一个上下文中表现得像数字,在另一个上下文下表现得像有方法调用的对象。

不可能让一个函数返回不同的值,这取决于是否对返回的值调用了另一个函数。您可以使用toString()(其中可以转换为字符串,或者在每个链的末尾调用另一个函数来获取值,而不是对象:

$test = new foo();
echo $test->doSomething1(); // Outputs 1
$test = new foo();
echo $test->doSomething1()->doSomething2(); // Outputs 3
$test = new foo();
$result = $test->doSomething1()->done(); // $result === 1
$test = new foo();
$result = $test->doSomething1()->doSomething2()->done(); // $result === 3
class foo {
    private $val;
    function __construct($val = 0){
        $this->val = $val;
    }
    function doSomething1(){
        $this->val += 1;
        return $this;
    }
    function doSomething2(){
        $this->val += 2;
        return $this;
    }
    function done(){
        return $this->val;
    }
    function __toString(){
        return (string)$this->val;
    }
}

编码板示例

这个答案建议在类上创建一个内部调用堆栈,这样您就可以跟踪方法链上的位置。这可以用于返回$this或其他内容,具体取决于上下文。