2013-07-29 3 views
1

Чтение this article и работало через пример Decorator. Код возвращает <strong></strong> вместо ожидаемого <strong><a href="logout.php">Logout</a></strong>.Отладка отладки PHP

class HtmlLinks { 
//some methods which is available to all html links 
} 

class LogoutLink extends HtmlLinks 
{ 
protected $_html; 

public function __construct() { 
$this->_html = "<a href=\"logout.php\">Logout</a>"; 
} 

public function setHtml($html) { 
$this->_html = $html; 
} 

public function render() { 
    echo $this->_html; 
} 
} 


class LogoutLinkStrongDecorator extends HtmlLinks { 
    protected $_logout_link; 

    public function __construct($logout_link) { 
    $this->_logout_link = $logout_link; 
    $this->setHtml("<strong>" . $this->_html . "</strong>"); 
    } 

    public function __call($name, $args) { 
    $this->_logout_link->$name($args[0]); 
    } 
} 

$logout_link = new LogoutLink(); 

$logout_link = new LogoutLinkStrongDecorator($logout_link); 
$logout_link->render(); 

Пробовал отлаживать весь день, но я не сделал никакого прогресса. Любое понимание было бы оценено.

ответ

1

Похоже, вы забыли вытащить _html из внутреннего объекта. Вам нужно добавить его к каждому методу конструктора каждого декоратора. В основном добавьте этот $ this -> _ html = $ _ linked_obj -> _ html.

+0

Это часть Я пытался решить. Я пытался сделать это в методе LogoutLinkStrongDecorator __construct (добавив '$ this -> _ html = $ logout_link -> _ html' или' $ this -> _ html = $ this -> _ logout_link -> _ html'). Но все, что я пробовал, приводит к ошибке, например: «Не удается получить доступ к защищенному свойству LogoutLink :: $ _ html' – verymystery

+0

изменить переменную на статическую. Вы также можете удалить расширения ... Я также думаю, что наиболее распространенным способом является использование интерфейса. – Bytemain

+0

Любое ключевое слово видимости работает после того, как я удалил главные символы подчеркивания из объявлений переменных. Изменен '$ this-> setHtml (" ". $ This -> _ html." ");' to '$ this-> setHtml (" ". $ This -> _ logout_link -> _ html." "); ' – verymystery

0

декоратор:

  1. Декоратора и декорированный объект реализовать тот же интерфейс.
  2. Декоратор принимает объект, реализующий общий интерфейс в своем конструкторе.

Вы не обязательно хотите, чтобы ваш декоратор наследовать от класса, который он декорирует. Вам просто нужно, чтобы он реализовал метод, который вам нужен, в контексте, который вы используете (в данном случае, «render()»), который вы можете обеспечить с помощью интерфейсов. Преимущество использования наследования является то, что все другие методы гарантированно еще быть отозваны, и вы также получите обратно экземпляр класса, который вы прошли в

Код:.

interface Renderable 
{ 
    public function render(); 
} 

class HtmlLink implements Renderable 
{ 
    public function render() 
    { 
     return '<a href="'.$this->href.'">'.$this->anchorText.'</a>'; 
    } 
    // other link methods... 
} 

class StrongRenderableDecorator implements Renderable 
{ 
    protected $renderable; 
    public function __construct(Renderable $renderable) 
    { 
     $this->renderable = $renderable; 
    } 
    public function render() 
    { 
     return '<strong>'.$this->renderable->render().'</strong>'; 
    } 
} 

$logout_link = new StrongRenderableDecorator(new LogoutLink()); 
$logout_link->render(); 
+0

Следовательно, урок неправильный 2 ошибки? – Bytemain

+0

Я не уверен, что вы имеете в виду. Это не производственный код, это псевдокод - есть четкая ссылка на два свойства (anchorText и href), которые не определены. Дело в том, что шаблон Decorator работает, реализуя общий интерфейс, а не наследуя от того же класса. – danonanimal

+0

Что значит производственный код? Я давно написал декоратора. – Bytemain

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