Можно ли узнать, происходит ли вызов метода из цепочки методов?
Например, у меня есть ниже class
:
class Test{
protected $string = '123';
public function a($string){
$this->string .= $string;
if(method chain){
return $this;
}else{
return $this->string;
}
}
public function b($string){
$this->string .= $string;
if(method chain){
return $this;
}else{
return $this->string;
}
}
}
Результат:
$test = new Test();
echo $test->a('000'); // 123000
echo $test->a('000')->b('www'); // 123000www
ОБНОВИТЬ
Я закончил тем, что создал exec()
метод, чтобы сказать больше никаких методов собирались вызывать.
public function exec(){
return $this->string;
}
Это невозможно, потому что вы не знаете о контексте, в котором будет использоваться результат метода.
Вместо этого вы всегда можете вернуться $this
справедливое использование __toString
способ вернуть ваш $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;
}
}
Затем, если вы подтвердите свое значение — он будет использовать его как строку, в противном случае вы будете работать с объектом.
PHP действительно обеспечивает debug_backtrace
для получения каждой функции, которая уже вызывается с указанием местоположения файла и номера строки. Но это не давало бы следующий вызов функции.
Используя расположение файла и номер строки, мы можем проанализировать исходный файл и получить цепочки.
getChains
Функция ниже будет работать на некотором стиле кодирования.
<?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;
}
}