PHP - 从链式函数调用中确定最后一个函数调用


PHP - determine last function-call from chained function-calls

使用链式函数时,有没有办法确定当前调用是否是链中的最后一个?

例如:

$oObject->first()->second()->third();

我想签入firstsecondthird调用是否是链中的最后一个,这样我就可以编写一个类似result的函数来始终添加到链中。在此示例中,检查应在 third 中为 true。

不,不以任何方式理智或可维护。
您必须添加done()方法或类似方法。

据我所知这是不可能的,我建议使用这样的整理方法:

$oObject->first()
  ->second()
  ->third()
  ->end(); // like this

如果你想在最后一个链上执行一个函数(没有额外的exec或在链上完成)。

下面的代码将从源代码中获取完整的链,并在最后一个链之后返回数据。

<?php
$abc = new Methods;
echo($abc->minus(12)->plus(32)); // output: -12+32
echo(
    $abc->plus(84)
    ->minus(63)
); // output: +84-63
class Methods{
    private $data = '';
    private $chains = false;
    public function minus($val){
        $this->data .= '-'.$val;
        return $this->exec('minus');
    }
    public function plus($val){
        $this->data .= '+'.$val;
        return $this->exec('plus');
    }
    private function exec($from){
        // Check if this is the first chain
        if($this->chains === false){
            $this->getChains();
        }
        // Remove the first chain as it's
        // already being called
        if($this->chains[0] === $from){
            array_shift($this->chains);
        }
        else
            die("Can't parse your chain");
        // Check if this is the last chain
        if(count($this->chains) === 0){
            $copy = $this->data;
            // Clear data
            $this->chains = false;
            $this->data = '';
            return $copy;
        }
        // If not then continue the chain
        return $this;
    }
    private function getChains(){
        $temp = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        // Find out who called the function
        for ($i=0; $i < count($temp); $i++) { 
            if($temp[$i]['function'] === 'exec'){
                $temp = $temp[$i + 1];
                break;
            }
        }
        // Prepare variable
        $obtained = '';
        $current = 1;
        // Open that source and find the chain
        $handle = fopen($temp['file'], "r");
        if(!$handle) return false;
        while(($text = fgets($handle)) !== false){
            if($current >= $temp['line']){
                $obtained .= $text;
                // Find break
                if(strrpos($text, ';') !== false)
                    break;
            }
            $current++;
        }
        fclose($handle);
        preg_match_all('/>('w.*?)'(/', $obtained, $matches);
        $this->chains = $matches[1];
        return true;
    }
}