2010-01-07 3 views
1

На мой взгляд (с использованием Zend_View поэтому вид является объектом), я делаю вызовы свойств объектов и методов для заполнения шаблона, как так:Как заставить метод вызывать свойство или метод объекта в PHP?

<?= $this->user->name ?> // Outputs John Doe 
<br/> 
<?= $this->user->getCompany()->name ?> // Outputs Acme 
<br/> 
<?= $this->method() ?> // Outputs foobar 

Если бы я сделать так, чтобы все запросы на недвижимость (как для «пользователя») пройти через __get() есть ли способ, которым я могу поймать последующие вызовы, чтобы я мог заставить вызов метода получить окончательное выведенное значение? Например, чтобы я мог выполнять автоматическое экранирование вывода.

Как я вижу это прямо сейчас, я либо должен избегать ввода, поскольку он входит в базу данных, либо использует скомпилированные шаблоны, такие как Smarty, или переключается на назначение каждой переменной объекту View, чтобы он имел прямое управление, чтобы заставить экранирование перед выводом данных.

+0

Я слышал, что в ZF 2.0 все возвращенный экземпляр Zend_View значения (возвращенные с помощью Zend_View :: __ get()) будут автоматически экранированы. –

+0

2 Проблемы: 2.0 еще нет и не будет на какое-то время из-за требований PHP 5.3. И это будут только значения автоматического выхода, которые назначаются ему напрямую, а не значения, полученные из объектов. –

ответ

1

Вы можете использовать декоратор. Смотрите этот упрощенный пример: (? Предполагая, что это метод Zend_View)

class ViewObject_Decorator 
{ 
    protected $_decoratedObject; 

    protected $_view; 

    public function __construct($object, Zend_View view) 
    { 
     $this->_decoratedObject = $object; 
     $this->_view = $view; 
    } 

    public function __get($property) 
    { 
     return $this->_view->escape($this->_decoratedObject->$property); 
    } 

    /* 
     maybe implement __call to proxy to decoratedObject methods, etc... 
    */ 
} 

Тогда вашего предложенного __get метода будет что-то вроде:

public function __get($property) 
{ 
    // decorate the requested object, and send the view along with it. 
    return new ViewObject_Decorator($this->$property, $this); 
} 
0

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

Для этого вам нужно использовать __get ($ var) в каждом классе, а затем вернуть переменную после ее выхода.

, вероятно, очень расточительно, хотя лично я бы использовать

<?= $this->user->escaped_name() ?> 

в классе для пользователя и класс, представляющий компанию

__get($var){ 
    if ($var == 'name') 
    return escape($this->name); 
} 

Это только один пример, и предполагает $ имя не является общественный член. если его необходимо будет элементом массива подходящей индексации в массиве, например:

return escape($this->data['name']); 

NB: У меня нет знания zend_views, но я предполагаю, что это не будет никакой разницы

DC

+0

Я не согласен, метод 'User :: escaped_name()' не принадлежит 'User', а что-то обрабатывает строки. – chelmertz

+0

Согласен, я только пытался придерживаться примера пользователей. лично, если бы мне пришлось использовать user-> name); ?> – DeveloperChris

0

Ручной способ заключается в использовании вид помощника побег() в шаблоне непосредственно, как это:

<?= $this->escape($this->user->name) ?> // Outputs John Doe 
<br/> 
<?= $this->escape($this->user->getCompany()->name) ?> // Outputs Acme 
<br/> 
<?= $this->escape($this->method()) ?> // Outputs foobar 

Самый простой способ автоматизировать это является использование потока обертку. Zend Framework предоставляет Zend_View_Stream, который используется для автоматизации преобразования коротких тегов в длинные теги. Это обеспечивается с помощью:

$view->setUseStreamWrapper(true); 

Вам нужно будет продлить его автоматически избежать любого использования <?=. Код для использования в обертке что-то вроде этого:

$find = '/<?=[ ]*([^;>]*?|[^;?]*?)[; ]*?>/'; 
$replace = "<?php echo $this->escape($1); ?>"; 
$this->data = preg_replace($find, $replace, $this->data); 

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

Дальнейшие подробности здесь:

+0

Я думаю, вы пропустили часть об автоматическом выходе из выхода. : P –

+0

Вы правы :) –

0

Вы можете расширить объект вида, а затем переопределить метод __get(), чтобы избежать всех выходов при необходимости.

Вы можете использовать:

$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); 
$viewRenderer->setView(new My_View()); 

изменить объект вида на тот, который вы создаете.

+0

Вот что я хочу сделать. Я спрашиваю, есть ли способ заставить вызов escape() для имени, которое является вызовом свойства объекта, который содержит Zend_View. –

0

Используйте PHPTAL как ваш view.

Он выполняет все по умолчанию (компилирует шаблоны для PHP, который имеет все необходимые htmlspecialchars() звонки, добавленные автоматически).

${this/user/getCompany/name} <!-- it's safe! --> 
Смежные вопросы