Documentation

ビュースクリプト - Zend_View

ビュースクリプト

コントローラが変数を代入して render() をコールすると、 指定されたビュースクリプトを Zend_View が読み込み、Zend_View インスタンスのスコープでそれを実行します。したがって、 ビュースクリプトの中で $this を参照すると、 実際には Zend_View のインスタンスを指すことになります。

コントローラからビューに代入された変数は、 ビューインスタンスのプロパティとして参照できます。例えば、 コントローラで変数 'something' を代入したとすると、 ビュースクリプト内ではそれを $this->something で取得できます (これにより、どの値がコントローラから代入されたもので、 どの値がスクリプト内部で作成されたものなのかを追いかけられるようになります)。

Zend_View の導入の部分で示したビュースクリプトの例を思い出してみましょう。

  1. <?php if ($this->books): ?>
  2.  
  3.     <!-- 本の一覧 -->
  4.     <table>
  5.         <tr>
  6.             <th>著者</th>
  7.             <th>タイトル</th>
  8.         </tr>
  9.  
  10.         <?php foreach ($this->books as $key => $val): ?>
  11.         <tr>
  12.             <td><?php echo $this->escape($val['author']) ?></td>
  13.             <td><?php echo $this->escape($val['title']) ?></td>
  14.         </tr>
  15.         <?php endforeach; ?>
  16.  
  17.     </table>
  18.  
  19. <?php else: ?>
  20.  
  21.     <p>表示する本がありません。</p>
  22.  
  23. <?php endif;?>

出力のエスケープ

ビュースクリプトで行うべき仕事のうち最も重要なもののひとつは、 出力を適切にエスケープすることです。これは、 クロスサイトスクリプティング攻撃を防ぐのを助けます。 それ自身がエスケープを行ってくれるような関数、メソッド、 あるいはヘルパーを使用しているのでない限り、 変数を出力する際には常にそれをエスケープしなければなりません。

Zend_View の escape() というメソッドが、このエスケープを行います。

  1. // ビュースクリプトの悪い例
  2. echo $this->variable;
  3.  
  4. // ビュースクリプトのよい例
  5. echo $this->escape($this->variable);

デフォルトでは、escape() メソッドは PHP の htmlspecialchars() 関数でエスケープを行います。しかし環境によっては、 別の方法でエスケープしたくなることもあるでしょう。 コントローラから setEscape() メソッドを実行することで、 エスケープに使用するコールバックを Zend_View に通知できます。

  1. // Zend_View のインスタンスを作成します
  2. $view = new Zend_View();
  3.  
  4. // エスケープに htmlentities を使用するように通知します
  5. $view->setEscape('htmlentities');
  6.  
  7. // あるいは、クラスの静的メソッドを使用するように通知します
  8. $view->setEscape(array('SomeClass', 'methodName'));
  9.  
  10. // あるいは、インスタンスメソッドを指定することもできます
  11. $obj = new SomeClass();
  12. $view->setEscape(array($obj, 'methodName'));
  13.  
  14. // そして、ビューをレンダリングします
  15. echo $view->render(...);

コールバック関数あるいはメソッドは、 エスケープする値を最初のパラメータとして受け取ります。 それ以外のパラメータはオプションとなります。

別のテンプレートシステムの使用

PHP 自身も強力なテンプレートシステムではありますが、 開発者の多くは、デザイナにとっては高機能すぎる/複雑すぎる と感じており、別のテンプレートエンジンをほしがっているようです。 Zend_View では、そのような目的のために二種類の仕組みを提供します。 ビュースクリプトを使用することによるものと、 Zend_View_Interface 実装することによるものです。

ビュースクリプトを使用したテンプレートシステム

ビュースクリプトを使用して、PHPLIB 形式のテンプレートのような 別のテンプレートオブジェクトのインスタンスを作成し、 それを操作できます。ビュースクリプトをこのように使用する方法は、 以下のようになります。

  1. include_once 'template.inc';
  2. $tpl = new Template();
  3.  
  4. if ($this->books) {
  5.     $tpl->setFile(array(
  6.         "booklist" => "booklist.tpl",
  7.         "eachbook" => "eachbook.tpl",
  8.     ));
  9.  
  10.     foreach ($this->books as $key => $val) {
  11.         $tpl->set_var('author', $this->escape($val['author']);
  12.         $tpl->set_var('title', $this->escape($val['title']);
  13.         $tpl->parse("books", "eachbook", true);
  14.     }
  15.  
  16.     $tpl->pparse("output", "booklist");
  17. } else {
  18.     $tpl->setFile("nobooks", "nobooks.tpl")
  19.     $tpl->pparse("output", "nobooks");
  20. }

関連するテンプレートファイルは、このようになります。

  1. <!-- booklist.tpl -->
  2. <table>
  3.     <tr>
  4.         <th>著者</th>
  5.         <th>タイトル</th>
  6.     </tr>
  7.     {books}
  8. </table>
  9.  
  10. <!-- eachbook.tpl -->
  11.     <tr>
  12.         <td>{author}</td>
  13.         <td>{title}</td>
  14.     </tr>
  15.  
  16. <!-- nobooks.tpl -->
  17. <p>表示する本がありません。</p>

Zend_View_Interface を使用したテンプレート

Zend_View 互換のテンプレートエンジンを使用するほうが簡単だという人もいるでしょう。 Zend_View_Interface では、 互換性を保つために最低限必要なインターフェイスを定義しています。

  1. /**
  2. * テンプレートエンジンオブジェクトを返します
  3. */
  4. public function getEngine();
  5.  
  6. /**
  7. * ビュースクリプト/テンプレートへのパスを設定します
  8. */
  9. public function setScriptPath($path);
  10.  
  11. /**
  12. * すべてのビューリソースへのベースパスを設定します
  13. */
  14. public function setBasePath($path, $prefix = 'Zend_View');
  15.  
  16. /**
  17. * ビューリソースへのベースパスを追加します
  18. */
  19. public function addBasePath($path, $prefix = 'Zend_View');
  20.  
  21. /**
  22. * 現在のスクリプトのパスを取得します
  23. */
  24. public function getScriptPaths();
  25.  
  26. /**
  27. * テンプレート変数をオブジェクトのプロパティとして代入するためのオーバーロードメソッド
  28. */
  29. public function __set($key, $value);
  30. public function __isset($key);
  31. public function __unset($key);
  32.  
  33. /**
  34. * テンプレート変数を手動で代入したり、複数の変数を
  35. * 一括設定したりします
  36. */
  37. public function assign($spec, $value = null);
  38.  
  39. /**
  40. * 代入済みのテンプレート変数を削除します
  41. */
  42. public function clearVars();
  43.  
  44. /**
  45. * $name というテンプレートをレンダリングします
  46. */
  47. public function render($name);

このインターフェイスを使用すると、 サードパーティのテンプレートエンジンをラップして Zend_View 互換のクラスを作成することが簡単になります。 例として、Smarty 用のラッパーはこのようになります。

  1. class Zend_View_Smarty implements Zend_View_Interface
  2. {
  3.     /**
  4.      * Smarty object
  5.      * @var Smarty
  6.      */
  7.     protected $_smarty;
  8.  
  9.     /**
  10.      * コンストラクタ
  11.      *
  12.      * @param string $tmplPath
  13.      * @param array $extraParams
  14.      * @return void
  15.      */
  16.     public function __construct($tmplPath = null, $extraParams = array())
  17.     {
  18.         $this->_smarty = new Smarty;
  19.  
  20.         if (null !== $tmplPath) {
  21.             $this->setScriptPath($tmplPath);
  22.         }
  23.  
  24.         foreach ($extraParams as $key => $value) {
  25.             $this->_smarty->$key = $value;
  26.         }
  27.     }
  28.  
  29.     /**
  30.      * テンプレートエンジンオブジェクトを返します
  31.      *
  32.      * @return Smarty
  33.      */
  34.     public function getEngine()
  35.     {
  36.         return $this->_smarty;
  37.     }
  38.  
  39.     /**
  40.      * テンプレートへのパスを設定します
  41.      *
  42.      * @param string $path パスとして設定するディレクトリ
  43.      * @return void
  44.      */
  45.     public function setScriptPath($path)
  46.     {
  47.         if (is_readable($path)) {
  48.             $this->_smarty->template_dir = $path;
  49.             return;
  50.         }
  51.  
  52.         throw new Exception('無効なパスが指定されました');
  53.     }
  54.  
  55.     /**
  56.      * 現在のテンプレートディレクトリを取得します
  57.      *
  58.      * @return string
  59.      */
  60.     public function getScriptPaths()
  61.     {
  62.         return array($this->_smarty->template_dir);
  63.     }
  64.  
  65.     /**
  66.      * setScriptPath へのエイリアス
  67.      *
  68.      * @param string $path
  69.      * @param string $prefix Unused
  70.      * @return void
  71.      */
  72.     public function setBasePath($path, $prefix = 'Zend_View')
  73.     {
  74.         return $this->setScriptPath($path);
  75.     }
  76.  
  77.     /**
  78.      * setScriptPath へのエイリアス
  79.      *
  80.      * @param string $path
  81.      * @param string $prefix Unused
  82.      * @return void
  83.      */
  84.     public function addBasePath($path, $prefix = 'Zend_View')
  85.     {
  86.         return $this->setScriptPath($path);
  87.     }
  88.  
  89.     /**
  90.      * 変数をテンプレートに代入します
  91.      *
  92.      * @param string $key 変数名
  93.      * @param mixed $val 変数の値
  94.      * @return void
  95.      */
  96.     public function __set($key, $val)
  97.     {
  98.         $this->_smarty->assign($key, $val);
  99.     }
  100.  
  101.     /**
  102.      * empty() や isset() のテストが動作するようにします
  103.      *
  104.      * @param string $key
  105.      * @return boolean
  106.      */
  107.     public function __isset($key)
  108.     {
  109.         return (null !== $this->_smarty->get_template_vars($key));
  110.     }
  111.  
  112.     /**
  113.      * オブジェクトのプロパティに対して unset() が動作するようにします
  114.      *
  115.      * @param string $key
  116.      * @return void
  117.      */
  118.     public function __unset($key)
  119.     {
  120.         $this->_smarty->clear_assign($key);
  121.     }
  122.  
  123.     /**
  124.      * 変数をテンプレートに代入します
  125.      *
  126.      * 指定したキーを指定した値に設定します。あるいは、
  127.      * キー => 値 形式の配列で一括設定します
  128.      *
  129.      * @see __set()
  130.      * @param string|array $spec 使用する代入方式 (キー、あるいは キー => 値 の配列)
  131.      * @param mixed $value (オプション) 名前を指定して代入する場合は、ここで値を指定します
  132.      * @return void
  133.      */
  134.     public function assign($spec, $value = null)
  135.     {
  136.         if (is_array($spec)) {
  137.             $this->_smarty->assign($spec);
  138.             return;
  139.         }
  140.  
  141.         $this->_smarty->assign($spec, $value);
  142.     }
  143.  
  144.     /**
  145.      * 代入済みのすべての変数を削除します
  146.      *
  147.      * Zend_View に {@link assign()} やプロパティ
  148.      * ({@link __get()}/{@link __set()}) で代入された変数をすべて削除します
  149.      *
  150.      * @return void
  151.      */
  152.     public function clearVars()
  153.     {
  154.         $this->_smarty->clear_all_assign();
  155.     }
  156.  
  157.     /**
  158.      * テンプレートを処理し、結果を出力します
  159.      *
  160.      * @param string $name 処理するテンプレート
  161.      * @return string 出力結果
  162.      */
  163.     public function render($name)
  164.     {
  165.         return $this->_smarty->fetch($name);
  166.     }
  167. }

この例では、Zend_View ではなく Zend_View_Smarty クラスのインスタンスを作成し、 それを使用して Zend_View と同じようなことをしています。

  1. //例 1. InitializerのinitView()で
  2. $view = new Zend_View_Smarty('/path/to/templates');
  3. $viewRenderer =
  4.     Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
  5. $viewRenderer->setView($view)
  6.              ->setViewBasePathSpec($view->_smarty->template_dir)
  7.              ->setViewScriptPathSpec(':controller/:action.:suffix')
  8.              ->setViewScriptPathNoControllerSpec(':action.:suffix')
  9.              ->setViewSuffix('tpl');
  10.  
  11. //例 2. アクションコントローラでも同様に...
  12. class FooController extends Zend_Controller_Action
  13. {
  14.     public function barAction()
  15.     {
  16.         $this->view->book   = 'Zend PHP 5 Certification Study Guide';
  17.         $this->view->author = 'Davey Shafik and Ben Ramsey'
  18.     }
  19. }
  20.  
  21. //例 3. アクションコントローラでのビューの初期化
  22. class FooController extends Zend_Controller_Action
  23. {
  24.     public function init()
  25.     {
  26.         $this->view   = new Zend_View_Smarty('/path/to/templates');
  27.         $viewRenderer = $this->_helper->getHelper('viewRenderer');
  28.         $viewRenderer->setView($this->view)
  29.                      ->setViewBasePathSpec($view->_smarty->template_dir)
  30.                      ->setViewScriptPathSpec(':controller/:action.:suffix')
  31.                      ->setViewScriptPathNoControllerSpec(':action.:suffix')
  32.                      ->setViewSuffix('tpl');
  33.     }
  34. }

Copyright

© 2006-2019 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts