Изменить класс объекта во время выполнения - PullRequest
0 голосов
/ 23 декабря 2008

Я работаю с CMS, Joomla, и есть базовый класс, который отображает набор параметров в форме, JParameter. По сути, он имеет функцию render(), которая выводит некоторый загруженный таблицей HTML, который не соответствует остальной части моего сайта.

Что касается вопросов сопровождения, и поскольку я понятия не имею, где еще это используется, я не хочу менять основной код. То, что было бы идеально, было бы в состоянии определить новый класс, который расширяет JParameter, а затем привести мой объект $ params к этому новому подклассу.

// existing code --------------------
class JParameter {
    function render() {
        // return HTML with tables
    }
    // of course, there's a lot more functions here
}

// my magical class -----------------
class MyParameter extends JParameter {
    function render() {
        // return HTML which doesn't suck
    }
}

// my code --------------------------
$this->params->render();    // returns tables
$this->params = (MyParameter) $this->params;  // miracle occurs here?
$this->params->render();    // returns nice html

Ответы [ 2 ]

3 голосов
/ 23 декабря 2008

Всегда есть PECL's Classkit , но я чувствую, что вы действительно не хотите этого делать. Предполагая, что вы непосредственно вызываете $this->params->render(), вы можете просто захотеть создать функцию / объект, который выполняет альтернативный рендеринг (MyParamRenderer::render($this->params)) и избегает выполнения ОО-гимнастики, изначально не поддерживаемой языком.

2 голосов
/ 23 декабря 2008

Как насчет создания своего рода декоратора, который делегирует что-либо кроме JParameter :: render () существующему объекту

class MyJParameter {
    private $jparm;
    function __construct( JParameter $jparm ) {
        $this->jparm = $jparm;
    }
    function render() {
        /* your code here */
    }
    function __get( $var ) {
        if( isset( $this->$jparm->$var ) {
            return $this->$jparm->$var;
        }
        return false;
    }
    function __set( $var, $val ) {
        /* similar to __get */
    }
    function __call( $method, $arguments ) {
        if( method_exists( $this->jparm, $method ) {
           return call_user_func_array( array( $this->jparm, $method ), $arguments );
        }
        return false;
    }
}

Или это слишком вонючий?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...