アルバムの一覧表示
設定、データベース情報、ビューの骨組みは完了したので、アプリケーションの主要部分に着手して、いくつかアルバムを表示させます。これは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!)を表示すると、下のようなアルバム一覧が見られるはずです。
アルバムの新規追加
アルバムの新規追加する機能を記述していきます。これは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 :)
目次
- Zend Framework チュートリアル その1 - チュートリアルの動作環境,Zend_Tool
- Zend Framework チュートリアル その2 - チュートリアルアプリケーション
- Zend Framework チュートリアル その3 - アプリケーションコードの作成,データベース,モデル
- Zend Framework チュートリアル その4 - レイアウトとビュー
- Zend Framework チュートリアル その5 - アルバムの一覧表示,最後に
