16.3. Скрипты вида

После того, как ваш контроллер определил переменные и вызвал метод render(), Zend_View включает требуемый скрипт представления и выполняет его "внутри" области видимости Zend_View. Поэтому в вашем скрипте представления ссылки на $this в действительности будут ссылаться на сам экземляр Zend_View.

Переменные, объявленные для вида в контроллере, ссылаются на свойства экземпляра. Например, если контроллер объявил переменную 'something', вы можете ссылаться на нее как на $this->something в скрипте вида (это дает вам возможность отслеживать, какие переменные были объявлены для скрипта, и какие были объявлены самим скриптом).

Для напоминания, здесь приведен пример скрипта представления из введения.

<?php if ($this->books): ?>
    
    <!-- Таблица нескольких книг. -->
    <table>
        <tr>
            <th>Author</th>
            <th>Title</th>
        </tr>
        
        <?php foreach ($this->books as $key => $val): ?>
        <tr>
            <td><?php echo $this->escape($val['author']) ?></td>
            <td><?php echo $this->escape($val['title']) ?></td>
        </tr>
        <?php endforeach; ?>
        
    </table>
    
<?php else: ?>
    
    <p>Нет книг для отображения.</p>
    
<?php endif; ?>
    

16.3.1. Экранизация вывода

Одной из наиважнейших задач, которую должен решать скрипт вида, является обеспечение того, что выходные данные должным образом экранизированны; помимо прочего, это помогает предотвратить XSS-атаки. За исключением тех случаев, когда используете функции, методы или вспомогательные классы, которые делают экранизацию сами, вы должны всегда экранизировать переменные, когда выводите их.

Zend_View снабжен методом escape(), который выполняет экранизацию.

<?php
// плохая практика для скриптов вида
echo $this->variable;

// хорошая практика для скриптов вида
echo $this->escape($this->variable);
?>
        

По умолчанию метод escape() использует функцию PHP htmlspecialchars() для экранизации. Но, в зависимости от вашего окружения, может потребоваться выполнять экранизацию по-иному. Используйте метод setEscape() на уровне контроллера, чтобы указать Zend_View, какую экранизирующую функцию обратного вызова использовать.

<?php
// создание экземпляра Zend_View
$view = new Zend_View();

// приказываем ему использовать htmlentities
// в качестве экранизирующей функции обратного вызова
$view->setEscape('htmlentities');

// либо приказываем ему использовать статический метод класса
$view->setEscape(array('SomeClass', 'methodName'));

// или даже метод экземпляра
$obj = new SomeClass();
$view->setEscape(array($obj, 'methodName'));

// и затем воспроизводим вид
echo $view->render(...);
?>
        

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

16.3.2. Шаблонизатор

Хотя PHP сам по себе представляет собой мощный шаблонизатор, многие разработчики считают его слишком мощным или сложным для верстальщиков. Как таковой, скрипт представления может использоваться для инстанцирования и манипулирования различными объектами шаблонов, такими, как шаблоны в стиле PHPLIB. Скрипты представления для такого рода действий должны выглядеть наподобие этого:

<?php
include_once 'template.inc';
$tpl = new Template();

if ($this->books) {
    $tpl->setFile(array(
        "booklist" => "booklist.tpl",
        "eachbook" => "eachbook.tpl",
    ));
    
    foreach ($this->books as $key => $val) {
        $tpl->set_var('author', $this->escape($val['author']);
        $tpl->set_var('title', $this->escape($val['title']);
        $tpl->parse("books", "eachbook", true);
    }
    
    $tpl->pparse("output", "booklist");
} else {
    $tpl->setFile("nobooks", "nobooks.tpl")
    $tpl->pparse("output", "nobooks");
}
?>
        

Это могло бы быть соответствующим файлом шаблона:

<!-- booklist.tpl -->
<table>
    <tr>
        <th>Author</th>
        <th>Title</th>
    </tr>
    {books}
</table>

<!-- eachbook.tpl -->
    <tr>
        <td>{author}</td>
        <td>{title}</td>
    </tr>

<!-- nobooks.tpl -->
<p>Нет книг для отображения.</p>