是否允许在PHP中链接调用方法?

coo*_*god 6 php method-chaining magic-methods

例如,我有以下内容:

class A{
  __invoke(){
    // return an instance of class A itself
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以这样做吗?

new A()()()()... or (new A())()()()...
Run Code Online (Sandbox Code Playgroud)

这是什么解释?假设PHP版本比5.4更新

好吧,我可以再解释一下为什么我要问:我正在使用ganon.php这是一个开源的html dom解析器.它使用类似$ html_node('child_tag')的语法来返回另一个子$ html_node,其中$ html_node是类HTML_NODE的对象实例.所以我在想是否可以使用链接在嵌套的html dom结构中进行选择.

Álv*_*lez 4

我不认为你描述的行为实际上有效,即使在 PHP/7 中也是如此:

class A{
    public function __invoke($arg){
        echo __METHOD__ . "($arg) called" . PHP_EOL;
    }
}

$a = new A();
$a(0);
$a(1)(2)(3);
Run Code Online (Sandbox Code Playgroud)
A::__invoke(0) called
A::__invoke(1) called
Fatal error: Function name must be a string
Run Code Online (Sandbox Code Playgroud)

演示

您可能对变量函数功能感到困惑。如果foo()返回“bar”字符串,则foo()()等于bar()

class A{
    public function __invoke(){
        return 'hello';
    }
}

function hello($name) {
    echo "Hello, $name!" . PHP_EOL;
}

$a = new A();
$a()('Jim');
Run Code Online (Sandbox Code Playgroud)
Hello, Jim!
Run Code Online (Sandbox Code Playgroud)

演示

只要您的函数返回更多具有有效函数名称的字符串,您就可以将其链接起来,但__invoke类和类都不会发挥任何相关作用:

function one() {
    return 'two';
}

function two() {
    return 'three';
}

function three() {
    return 'four';
}

function four() {
    echo 'Done!';
}

$a = one()()()();
Run Code Online (Sandbox Code Playgroud)
function one() {
    return 'two';
}

function two() {
    return 'three';
}

function three() {
    return 'four';
}

function four() {
    echo 'Done!';
}

$a = one()()()();
Run Code Online (Sandbox Code Playgroud)

演示

注意:上面的所有代码片段都需要 PHP/7,但只需使用适当的括号和中间变量就可以用早期版本来模拟它们。


根据 UlrichEckhardt 的评论进行更新:我忽略了返回 A 类本身的实例评论。如果你真的这样做,代码确实有效:

class A{
    public function __invoke($arg){
        echo __METHOD__ . "($arg) called" . PHP_EOL;
        return $this;
    }
}

$a = new A();
$a(0);
$a(1)(2)(3);
Run Code Online (Sandbox Code Playgroud)

class A{
    public function __invoke($arg){
        echo __METHOD__ . "($arg) called" . PHP_EOL;
        return $this;
    }
}

$a = new A();
$a(0);
$a(1)(2)(3);
Run Code Online (Sandbox Code Playgroud)

演示

当然,这是 PHP/7 语法。对于旧版本,您需要破坏魔法的辅助变量:

$a = new A();
$b = $a(1);
$c = $b(2);
$d = $c(3);
$d(4);
Run Code Online (Sandbox Code Playgroud)