Проверьте, является ли вызов цепочкой метода

Можно ли узнать, происходит ли вызов метода из цепочки методов?
Например, у меня есть ниже 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;
}

3

Решение

Это невозможно, потому что вы не знаете о контексте, в котором будет использоваться результат метода.

Вместо этого вы всегда можете вернуться $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;
}
}

Затем, если вы подтвердите свое значение — он будет использовать его как строку, в противном случае вы будете работать с объектом.

2

Другие решения

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;
}
}
0

По вопросам рекламы [email protected]