Category

Zend Framework チュートリアル その5 - アルバムの一覧表示,最後に

アルバムの一覧表示

設定、データベース情報、ビューの骨組みは完了したので、アプリケーションの主要部分に着手して、いくつかアルバムを表示させます。これはIndexControllerクラス内で行い、indexAction()関数内で表にアルバムを一覧表示させることから始めます。

zf-tutorial/application/controllers/IndexController.php

...
function indexAction()
{
    $albums = new Application_Model_DbTable_Albums();
    $this->view->albums = $albums->fetchAll();
}
...

テーブルデータゲートウェイベースのモデルのインスタンスをインスタンス化します。fetchAll()関数は、Zend_Db_Table_Rowsetを返し、結果の一覧をこのアクションのビュースクリプトファイル内で反復処理出来るようにします。

では、関連付けられたビュースクリプト index.phtml を編集していきます。

zf-tutorial/application/views/scripts/index/index.phtml

<?php
$this->title = "My Albums";
$this->headTitle($this->title);
?>
<p><a href="<?php echo $this->url(array('controller'=>'index',
		'action'=>'add'));?>">Add new album</a></p>
<table>
<tr>
    <th>Title</th>
    <th>Artist</th>
    <th>& </th>
</tr>
<?php foreach($this->albums as $album) : ?>
<tr>
    <td><?php echo $this->escape($album->title);?></td>
    <td><?php echo $this->escape($album->artist);?></td>
    <td>
        <a href="<?php echo $this->url(array('controller'=>'index',
            'action'=>'edit', 'id'=>$album->id));?>">Edit</a>
        <a href="<?php echo $this->url(array('controller'=>'index',
            'action'=>'delete', 'id'=>$album->id));?>">Delete</a>
    </td>
</tr>
<?php endforeach; ?>
</table>

最初にやっていることは、(レイアウトで使用されている)ページのタイトルを設定し、headTitle() ビューヘルパーを使って、ブラウザのタイトルバーに表示される<head>セクションの値も設定しています。それから新規アルバムを追加するリンクを作成しています。url()ビューヘルパーはフレームワークで用意されており、正しいbase URLを含んだリンクを作るのを助けてくれます。必要なパラメータは配列として渡すだけで、必要に応じて結果が返ってきます

アルバム追加のリンク作成です。url()ビューヘルパーはフレームワークで用意されており、正しいbase URLを含んだリンクを作るのを助けてくれます。必要なパラメータは配列として渡せば、必要に応じて結果が返ってきます。

各アルバムのタイトル、アーティスト、編集・削除のためのリンクを作成します。標準的なforeach:ループをアルバム一覧の反復処理に使います。代替書式のコロンとendforeach;を使います。このほうがブレースを組み合わせるよりも簡単です。
再度、このurl()ビューヘルパーを編集、削除リンクの作成に使います。

http://localhost/zf-tutorial/public (or wherever you are following along from!)を表示すると、下のようなアルバム一覧が見られるはずです。

tut03

アルバムの新規追加

アルバムの新規追加する機能を記述していきます。これは2つの部分で出来ています。

  • ユーザーに詳細データのフォームを表示する
  • フォーム送信処理とデータベースへの保存

これにはZend_Formを使います。Zend_Formコンポーネントはフォームの作成と入力値のバリデートを行います。フォームを定義するためにZend_Formを継承してForm_Albumクラスを作成します。これはアプリケーションリソースなので、formsディレクトリの中にAlbum.phpファイルとしてこのクラスを保存します。適切にファイルを作成するためにzfコマンドラインスクリプトを使います。

zf create form Album

これでapplication/forms にAlbum.phpが作成されます。これには、init()メソッドが含まれていて、ここにフォームをセットアップして、必要な要素を追加します。application/forms/Album.php を開き、init()メソッドのコメントを削除して以下のコードを追加します。

zf-tutorial/application/forms/Album.php

<?php
class Application_Form_Album extends Zend_Form
{
    public function init()
    {
	$this->setName('album');

	$id = new Zend_Form_Element_Hidden('id');
        $id->('Int');

	$artist = new Zend_Form_Element_Text('artist');
	$artist->setLabel('Artist')
		->setRequired(true)
		->addFilter('StripTags')
		->addFilter('StringTrim')
		->addValidator('NotEmpty');

	$title = new Zend_Form_Element_Text('title');
	$title->setLabel('Title')
		->setRequired(true)
		->addFilter('StripTags')
		->addFilter('StringTrim')
		->addValidator('NotEmpty');

	$submit = new Zend_Form_Element_Submit('submit');
	$submit->setAttrib('id', 'submitbutton');

	$this->addElements(array($id, $artist, $title, $submit));
    }
}

Application_Form_Albumのinit()メソッド内で、id,artist,title,submitボタンの4つのフォーム要素を作成します。各項目には表示用のラベルを含めた色々な属性をセットします。idには潜在的なSQLインジェクションの問題を防ぐためにintegerだけ受け付けることを保証したいので、Intフィルターを使用します。

テキスト要素には望まないHTMLや不要な空白文字を削除するためにStripTagsとStringTrimの2つのフィルターを追加します。ユーザーが確実に情報を入力するように、必須項目に設定してNotEmptyバリデータを追加します。(NotEmptyバリデータは、setRequired()がtrueにセットされるとシステムにより自動的に追加されるので、技術的には不要です。ここではどのようにバリデータを追加するのかを示すために追加しています。)

表示するフォームを取得して、送信処理をしてみましょう。これはIndexControllerのaddAction()内で行います。

zf-tutorial/application/controllers/IndexController.php
...
function addAction()
{
    $form = new Application_Form_Album();
    $form->submit->setLabel('Add');
    $this->view->form = $form;

    if ($this->getRequest()->isPost()) {
        $formData = $this->getRequest()->getPost();
        if ($form->isValid($formData)) {
            $artist = $form->getValue('artist');
            $title = $form->getValue('title');
            $albums = new Application_Model_DbTable_Albums();
            $albums->addAlbum($artist, $title);

            $this->_helper->redirector('index');
        } else {
            $form->populate($formData);
        }
    }
}
...

もう少し詳しく見てみましょう。

$form = new Application_Form_Album();
$form->submit->setLabel('Add');
$this->view->form = $form;

Form_Albumを生成して、submitボタンのラベルに"Add"を追加、それをレンダリングするためにビューに割り当てます。

if ($this->getRequest()->isPost()) {
    $formData = $this->getRequest()->getPost();
    if ($form->isValid($formData)) {

リクエストオブジェクトのisPost()メソッドがtrueなら、フォームが送信されているのでgetPost()を使ってリクエストからフォームデータを取得します。そして、isValid()メンバー関数を使って妥当性の確認をします。

$artist = $form->getValue('artist');
$title = $form->getValue('title');
$albums = new Model_DbTable_Albums();
$albums->addAlbum($artist, $title);

フォームがvalidなら、Application_Model_DbTable_Albumsモデルクラスを生成して、データベースに新しいレコードを追加するために先ほど用意したaddAlbum()メソッドを使います。

$this->_helper->redirector('index');

新しいアルバムが追加された後、Redirectorアクションヘルパーを使ってindexアクション(i.e ホームページに戻る)にリダイレクトします。

} else {
    $form->populate($formData);
}

フォームデータがvalidでなければ、ユーザーの入力データをフォームにいれて再表示します。

フォームを表示するためにadd.phtmlビュースクリプトを用意します。

zf-tutorial/application/views/scripts/index/add.phtml

<?php
$this->title = "Add new album";
$this->headTitle($this->title);
echo $this->form;
?>

見ての通り、フォームの描画は非常にシンプルです。フォーム自身が描画方法を知っているのでecho するだけです。

アルバムの編集

アルバムの編集は追加とほとんど一緒なので、コードもほとんど同じです。

zf-tutorial/application/controllers/IndexController.php

...
function editAction()
{
    $form = new Application_Form_Album();
    $form->submit->setLabel('Save');
    $this->view->form = $form;
    if ($this->getRequest()->isPost()) {
        $formData = $this->getRequest()->getPost();
        if ($form->isValid($formData)) {
            $id = (int)$form->getValue('id');
            $artist = $form->getValue('artist');
            $title = $form->getValue('title');
            $albums = new Application_Model_DbTable_Albums();
            $albums->updateAlbum($id, $artist, $title);
            $this->_helper->redirector('index');
        } else {
            $form->populate($formData);
        }
    } else {
        $id = $this->_getParam('id', 0);
        if ($id > 0) {
            $albums = new Application_Model_DbTable_Albums();
            $form->populate($albums->getAlbum($id));
        }
    }
}
...

アルバムの追加との違いを見てみましょう。最初にユーザーにフォームを表示するとき、アルバムのアーティストとタイトルをデータベースから取得して、フォーム要素に入れる必要があります。メソッドの下部がそれです。

$id = $this->_getParam('id', 0);
if ($id > 0) {
    $albums = new Application_Model_DbTable_Albums();
    $form->populate($albums->getAlbum($id));
}

これはリクエストがPOSTでなければ実行されることに注目してください。POSTの場合は、フォームが入力されていて、処理をするという意味です。フォームの初期表示のために、_getParam()メソッドを使ってリクエストからidを取得します。モデルを使ってデータベースの行を取得して、行データを直接フォームに入れています。(これでモデルのgetAlbum()メソッドがなぜ配列を返すかが理解できます)

フォームをバリデートした後、データを取得したデータベース行に保存します。これはモデルのupdateAlbum()メソッドを使って行います。

$id = $form->getValue('id');
$artist = $form->getValue('artist');
$title = $form->getValue('title');
$albums = new Application_Model_DbTable_Albums();
$albums->updateAlbum($id, $artist, $title);

ビューテンプレートはadd.phtmlとおなじです。

zf-tutorial/application/views/scripts/index/edit.phtml

<?php
$this->title = "Edit album";
$this->headTitle($this->title);
echo $this->form;
?>

これで追加と編集ができるようになりました。

アルバムの削除

このアプリケーションを完成させるためには削除機能が必要です。一覧ページの各アルバムの隣に削除リンクがあります。クリックされると削除するのは非常に単純な方法ですが、この方法は良くありません。HTTPの仕様を思い出しましょう、GETを使って取り返しのつかないことをすべきではない。代わりにPOSTを使うべきです。

ユーザーが削除をクリックしたら確認フォームを表示して、"はい"をクリックしたら削除を実行します。このフォームは瑣末なものなので、ビューに直接書いています。

IndexController::deleteAction()にアクションのコードを書きましょう。

zf-tutorial/application/controllers/IndexController.php

...
public function deleteAction()
{
    if ($this->getRequest()->isPost()) {
        $del = $this->getRequest()->getPost('del');
        if ($del == 'Yes') {
            $id = $this->getRequest()->getPost('id');
            $albums = new Application_Model_DbTable_Albums();
            $albums->deleteAlbum($id);
        }
        $this->_helper->redirector('index');
    } else {
        $id = $this->_getParam('id', 0);
        $albums = new Application_Model_DbTable_Albums();
        $this->view->album = $albums->getAlbum($id);
    }
}
...

追加と削除の場合と同様に、確認フォームを表示するか削除を行うかを判定するためにリクエストのisPost()メソッドを使います。実際の行の削除にはApplication_Model_DbTable_AlbumsモデルのdeleteAlbum()メソッドを使います。リクエストがPOSTでなければ、idパラメータを探して正しいデータベースのレコードを取得してビューにアサインします。

ビュースクリプトはシンプルなフォームです。

zf-tutorial/application/views/scripts/index/delete.phtml

<?php
$this->title = "Delete album";
$this->headTitle($this->title);
?>
<p>Are you sure that you want to delete
    '<?php echo $this->escape($this->album['title']); ?>' by
    '<?php echo $this->escape($this->album['artist']); ?>'?
</p>
<form action="<?php echo $this->url(array('action'=>'delete')); ?>" method="post">
<div>
    <input type="hidden" name="id" value="

このスクリプトでは、ユーザーに確認メッセージと”はい”、“いいえ”ボタンのフォームを表示します。アクション内で、明確に"はい"の確認をしてから削除します。

以上です。これで完全に動作するアプリケーションが完成しました。

最後に

これで、Zend Frameworkを使ったシンプルですが十分な機能を持つMVCアプリケーションを作成するという我々の記事も終了です。 あなたに興味を持ってもらえ、かつ参考になれば幸いです。もし誤りがあれば、どうか rob at akrabat dot com までメールしてください!

このチュートリアルはフレームワークの基本的な使い方について見てきました。探求するコンポーネントはまだまだあります!多くの説明を省略してもいます。私のウェブサイト http://akrabat.com/はZend Frameworkについての多くの記事があります。また、マニュアル(http://framework.zend.com/manual)も読むべきです。

最後に、印刷物を希望なら私が著したZend Framework in Action という書籍が購入可能です。 詳細は http://www.zendframeworkinaction.com で。Check it out :)


目次

  1. Zend Framework チュートリアル その1 - チュートリアルの動作環境,Zend_Tool
  2. Zend Framework チュートリアル その2 - チュートリアルアプリケーション
  3. Zend Framework チュートリアル その3 - アプリケーションコードの作成,データベース,モデル
  4. Zend Framework チュートリアル その4 - レイアウトとビュー
  5. Zend Framework チュートリアル その5 - アルバムの一覧表示,最後に

deliciousdiggfacebookgooglelinkedinstumbleupontwitter

Tags: