zerosp.blog > PHP > 2008/05/19 16:15 >

[学習 cakePHP #03] Guest Bookの機能を考える。indexメソッドの作成

さて前回はモデル、ビュー、コントローラの雛形を作成したところで終わりました。今回からGuest Bookの機能を実装していきます。使用するコントローラー名をboardsと決めたのでURIは。

http://localhost/guestbook/boards/メソッド名(アクション)/パラメータ

Guest Bookとして必要な機能はなんだろうか?

欲しい機能を考えてみると、記事一覧(index)、記事投稿(post)に加えて、編集(edit)、削除(del)、パーマリンク(view)ってところでしょうか。これらの機能をコントローラーにメソッドとして実装していきます。括弧内をメッソッド名とします。

まずはコントローラーのindexメソッドを作っていきます。データベースのテーブル(boards)を作成しただけで、データはまだ空なのでphpMyAdminからSQLにてデータを追加。

INSERT INTO boards (name, title, body, created)
  VALUES ('イチロー', '晴れ', '本日は晴天なり。', NOW());
INSERT INTO boards (name, title, body, created)
  VALUES ('ゴンザレス', '防衛', '今日の試合もタイトル防衛。', NOW()+3605);

とりあえず2件のデータを追加してみました。

コントローラにindexメソッドを作成。

indexメソッドは機能的に記事の一覧データの取得になります。

<?php
  class BoardsController extends AppController {
    var $name = 'Boards';
    function index() {
      $this->set("posts", $this->Board->findAll());
    }
  }
?>

なんとこの1行だけで、boardsテーブルからデータを取得できる!フレームワークって凄いです。実際には extends AppController とAppControllerを継承しているので、裏で継承元さんがバリバリと仕事をしているんですが・・・。

$this->set("変数名", データ);

setの名前が示すように、データを変数にセット(代入)します。上記の例ですとBoardモデルを通して取得したboardsテーブルのデータをpostsにセットします。そしてビュー(index.thtml)に渡します。変数にセットできるデータは値や、数値、配列なんかですね。セットした変数をビューで扱えます。↑だと $posts としてビュー(index.thtml)の中で扱うことができます。

findAll()

さてfindAll()です。データベースからデータを取得する関数です。

findAll($conditions, // 検索条件
        $fields,    // 取り出すフィールド
        $order,     // 順序(Sort)
        $limit,     // 1度に取得する件数
        $page,      // 取得するページ番号
        $recursive  // 再帰的に扱う場合の階層の深さ。
)

今回は引数指定をしてませんが実際には↑のようになります。findAll() は findAll(null, null, null, null, 1) と同じです。いま作っているゲストブックは取りあえずcakePHPとPHPに慣れる目的で作っているので例に沿って findAll()を引数指定なしで使いました。実際には findAll(null, null, "id desc", 10, 2) ってな感じで使うようなことになると思います。これだとデータをIDの降順で並べてから11~20番目のデータを取得って感じです。

ここでイマイチ分からないのが $this です。なんとなくコントローラーのインスタンスかなんかだろうとは思うんだけど、ググってみてもうまく検索で探すことが出来なかった・・・。PHPのリファレンスを探せば載ってるのかな?

indexメソッドに対応するビュー(index.thtml)を作成する。

C:\xampp\htdocs\guestbook\app\views フォルダへ作成したビューのテンプレ(index.thtml)へデータの表示関連を追記していきます。試しに1行記入してみましょう。

<?php pr($posts) ?>

pr(変数)は、$postsのデータの中身を表示してくれます。もし配列だった場合は配列の内容を展開して表示してくれるので便利です。ちなみにこのpr関数は

<?php echo "<pre>" . print_r($posts) . "</pre>"; ?>

と同じものです。print_rをcakePHPにて短縮表記にしたのがprになります。cakePHPにはこのように短縮表記にした関数がいくつか用意されています。

// pr($posts)
Array (
    [0] => Array (
        [Board] => Array (
            [id] => 2
            [name] => ゴンザレス
            [title] => 防衛
            [body] => 今日の試合もタイトル防衛。
            [created] => 2008-05-19 09:57:46
            [modified] => 
        )
    )
    [1] => Array (
        [Board] => Array (
            [id] => 1
            [name] => イチロー
            [title] => 晴れ
            [body] => 本日は晴天なり。
            [created] => 2008-05-19 09:21:41
            [modified] => 
        )
    )
)

ちょっと整形しましたが、まだデータは2件だけなのでこんな感じの配列データです。配列からデータを取り出しての処理はphpでもperlと同じforeachです。もちろん文法が多少違いますが・・・。Perlだと、

foreach $var (@array) {
    ~処理~
}

ってな感じで@array[0]を$varへ入れて、処理してくんだけどphpの場合は

<?php
  foreach ($array as $val) {
    ~処理~
  }
?>

もしくは

<?php foreach ($array as $val): ?>
    ~処理~
<?php endforeach; ?>

配列データにアクセスするには $val["Board"]["name"] で名前にアクセスできます。データ一覧表示に加えて投稿フォームを入れた index.thtmlは

<?php foreach ($posts as $post): ?>
  <div class="book" style="margin-bottom: 2em;">
    <p>ID: <?php echo $post["Board"]["id"] ?></p>
    <p>タイトル: <?php echo $post["Board"]["title"] ?></p>
    <p>名前: <?php echo $post["Board"]["name"] ?></p>
    <p>本文: <?php echo $post["Board"]["body"] ?></p>
    <p>投稿日時: <?php echo $post["Board"]["created"] ?></p>
  </div>
<?php endforeach; ?>

<div id="form">
  <p id="fheader">メッセージフォーム</p>
  <form method="post" action="<?php echo $html->url("/boards/post") ?>">
  <dl>
    <dt>title : </dt>
    <dd><?php echo $html->input("Board/title", array("size" => "35")) ?></dd>
    <dt>name : </dt>
    <dd><?php echo $html->input("Board/name", array("size" => "35")) ?></dd>
    <dt>body : </dt>
    <dd><?php echo $html->textarea("Board/body", array("rows" => "5", "cols" => "50")) ?></dd>
  </dl>
  <p><?php echo $html->hidden("Board/id") ?>
    <?php echo $html->submit("post", array("class" => "sb")) ?></p>
  </form>
</div>

foreachの部分は大丈夫なんだけどform部分のところで $html->input とか見慣れないものあります。これはcakePHPのHTMLヘルパーと呼ばれているものでリンクやフォームの生成の手助けをしてくれるものです。他にもJavascriptやAjaxヘルパーなんてものがあるそうです。

<input name="data[Board][name]" size="35" value="" type="text" id="BoardName" />

こう書かなければいけないところをhtmlヘルパーを使うと

<?php echo $html->input("Board/name", array("size" => "35")) ?>

と簡単です。index.thtmlを保存して http://localhost/guestbook/boards/ へアクセス。

とこんな感じで表示されれば今回は任務完了です。と書き忘れ・・・。

<p>タイトル: <?php echo $post["Board"]["title"] ?></p>

ここの箇所なんだけど、このままだとフォームからの入力時にタグが入っているとそのまんま表示されちゃうので、

<p>タイトル: <?php echo h($post["Board"]["title"]) ?></p>

としてみました。タイトル、名前、本文の箇所を変更。h()はphpのhtmlspecialchars()のパラメータなしの短縮表記のようです。特殊文字を HTML エンティティに変換します。とこんな感じでしょうか。自分の作業ログを兼ねて書いているので凄く長くなってしまった・・・。次回からはもっと短くなるようにしよう。

今回覚えた関数とか。
cakePHP → set, findAll(), pr, HTMLヘルパ, h
PHP → print_r, foreach, htmlspecialchars

投稿日 2008-05-19 16:15

当サイトのコメントとトラックバックの扱いについて。

スパム対策のため認証制となっています。受け取ったコメント、トラックバックは一旦保留扱いとなり管理人が許可したものだけ表示されます。

トラックバック

トラックバックの受付は停止中です。

コメント

コメントの受付は停止中です。