2012-01-10 5 views
1

я наткнулся на множество примеров метода построения цепочки в PHP, но не смог найти ничего об этом, так что я прошу помочь вам, ребята;)Метод цепочки без окончательного метода

Моя проблема - может Я каким-то образом узнаю, является ли метод в цепочке последним? В большинстве случаев люди используют какой-то окончательный метод (execute, send, ..), чтобы указать, когда цепочка заканчивается и возвращает соответствующий результат. Но мне интересно, есть ли какой-нибудь скрытый магический метод или техника, чем можно проверить все методы в цепочке и определить, нет ли следующего метода? Без конечного метода он отлично работает для строк (в очень простом примере), но не для того, чтобы вернуть массив.

Вот мой сниппет:

class Chain { 
    private $strArray; 

    function __call($name, $args) { 
     $this->strArray[] = $args[0]; 
     return $this; 
    } 
    function __toString() { 
     return implode('-', $this->strArray); 
    } 
} 
// example 1 
$c = new Chain(); 
$x = $c->foo('hi')->bar('stack'); // need array('hi', 'stack') 

// example 2 
$c = new Chain(); 
$x = $c->foo('hi')->bar('stack')->foobar('overflow'); // need array('hi', 'stack', 'overflow') 

// example 3 
$c = new Chain(); 
echo $c->foo('hi')->foobar('overflow'); // prints 'hi-overflow' 

// example 4 
$c = new Chain(); 
echo $c->foo('hi')->bar('stack')->foobar('overflow'); // prints 'hi-stack-overflow' 

Вы видите, когда я хочу, чтобы распечатать результат цепи, я могу изменить результат в методе __toString, но что, если я нужен массив (пример 1, 2)? Есть ли способ достичь этого, не вызывая какого-то дополнительного «окончательного» метода?

Большое спасибо за помощь и сообщите мне, если вам нужна дополнительная информация.

EDIT: После обратной связи от @bandi я попытался расширить ArrayObject вот так.

class Chain extends ArrayObject { 
    function __call($name, $args) { 
     $this->append($args[0]); 
     return $this; 
    } 
    function __toString() { 
     return implode('-', $this->getIterator()->getArrayCopy()); 
    } 
} 
// returned ref. to object, works fine in loop or accessing offset 
$obj = new Chain; 
$x = $obj->foo('hi')->bar('stack')->foobar('overflow'); // need array('hi', 'stack', 'overflow') 
foreach ($x as $y) { 
    echo $y, "\n"; 
} 
var_dump($x[0], $x[1], $x[2]); 

// returned String 
$c = new Chain; 
echo $c->foo('hi')->foobar('overflow'); // prints 'hi-overflow' 

Это то, что я хотел, но я не чувствую себя так хорошо о $this->getIterator()->getArrayCopy() части. Есть ли простой способ доступа к массиву (внутренне в ["storage":"ArrayObject":private])? Thanks

ответ

0

Цепочка метода использует возвращаемое значение функции, в этом случае это ссылка на объект. Предсказание использования возвращаемого значения, как правило, невозможно.

Вы должны сообщить вызываемому методу, что хотите сделать что-то другое. Вы можете использовать второй аргумент для этого, например. вы возвращаете другой результат, если задан второй аргумент. Другой вариант может состоять в том, чтобы изменить класс, чтобы он вел себя как массив, за исключением того, что он напечатан.

+0

ОК, спасибо. Как правило, я хотел бы возвращать массив при назначении переменной, но у меня есть опция open для строки в строку. Когда я возвращаю $ this, я не получаю свойство класса ($ strArray), а целую ссылку на класс, что нежелательно, и это заставляет меня реализовать «окончательный» метод. Но, возможно, самый простой способ - передать второй аргумент TRUE последнему методу в цепочке, как вы предложили. Я посмотрю, придут ли дополнительные советы;) – lp1051

+0

кстати. как вы имели в виду - «Другой вариант может состоять в том, чтобы изменить класс, чтобы он вел себя как массив, за исключением того, что он напечатан». ?? Я не уверен, что понимаю – lp1051

+0

@ lp1051 Я не совсем знаком с системой классов php в более новых версиях, поэтому я не знаю, возможно ли это или нет: я имел в виду, что вы вывели свой класс из класса «array» и затем добавьте два собственных метода. – bandi

Смежные вопросы