Check if call is method chaining

杀马特。学长 韩版系。学妹 提交于 2019-12-06 01:58:14

It's not possible because you do not know about the context that method's result will be used.

Instead of it, you can always return $this an just use __toString method to retur your $string:

class Test{
    protected $string = '123';

    public function a($string){
        $this->string .= $string;
        return $this;
    }

    public function b($string){
        $this->string .= $string;
        return $this;
    }

    public function __toString() {
        return $this->string;
    }
}

Then if you'll echo your value - it will use it as a string, otherwise you'll work on an object.

PHP does provide debug_backtrace for retrieving every function that already being called with the file location and line number. But it wouldn't giving what's the next function call.

By using the file location and line number, we can parse the source file and get the chains.

The getChains function below to will work on some coding style.

<?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;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!