初めてのsymfony〜PEARインストール編パート2

実践編もパート2を迎えいよいよクライマックスの3っつ前ぐらいです。

symfonyで動くものを作ってみるお話。


では早速動くものを作っていくとします。
Hello World?何それ?時間の無駄です。
というより、とりあえず表示させるだけも、動くものを作るのもあまり時間はかわらない。しかし!理解は数百倍深まるので、いきなり動くものを作る。これ真理かも。


ここからプロジェクトのディレクトリにいるとして、相対パスで書いていきます。
ちなみに私は、すべてターミナルから作業しました。(ホントです)


さてさて、モジュールを生成から。

symfony init-module myapp mymodule

もう慣れたと思いますが、上のコマンドだけでモジュールのひな形が自動生成されます。
ここで、htaccessの設定を行います。
すでに、web以下に自動生成されているものを修正します。
少し余分な設定があるので、以下の行を残して残りの設定をコメントアウトします。
web/.htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

http://symfony.localserver/mymodule
ここにアクセスすると、moduleなんとかsuccess!と表示されるはずです。
これでモジュールができました!


ここでは簡単な投稿システムを作りながら、symfonyのすごさを体感しましょう。

symfony」でデータベースを生成してテーブルを作ります。

CREATE TABLE `posts` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `text` text NOT NULL,
  `modified` timestamp NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

手抜きですみません。。。

DBの設定をyamlに記述します。
yamlの事はすっ飛ばしますが、インデットが命です!解らない人は、必ず正確にコピペ職人に徹しましょう。
スキーマの設定。まぁテーブルの設定と言うことで。
config/schema.yml

propel:
  posts :
    _attributes: { phpName: Post }
    id:
    title:       varchar(255)
    text:        longvarchar
    modified: timestamp

DBの基本設定です。
config/databases.yml

all:
  propel:
    class:          sfPropelDatabase
    param:
      phptype:      mysql
      hostspec:     localhost
      database:     symfony
      username:     symfony_user
      password:     secret_pass

DBのモデルを生成します。これまた自動です。cache削除を忘れずに。

symfony propel-build-model
symfony clear-cache

キャッシュ削除と書きましたが、symfonyではyamlの設定とか、クラスファイルの場所とか、なんでもキャッシュ化しているので、ちょっと変更するたびにキャッシュをクリアする必要があるんですね。


次にコントローラを修正します。
apps/myapp/modules/mymodule/actions/actions.class.php
executeIndex内のforwardを行っている行をコメントアウトします。

さぁこれで、もう一度さっきのURLにアクセス。
http://symfony.localserver/mymodule

何が表示されましたか?
何も表示されない??そうす!それが正解です。
forwardして表示されていたさっきのsymfony画面が、コメントアウトしたことで表示されなくなったのです。
続いて、templateを修正しましょう。

apps/myapp/modules/mymodule/templates/indexSuccess.php
ここにてきとーに「Hello Worl」とでも入力して、mymoduleに再びアクセスしましょう。
ちゃんと入力した内容が表示されていますね。

ここで、表示された画面のソースを見てみましょう。
そうです!htmlのヘッダが出力されています。
symfonyでは最初からレイアウト構造ができているのです。いやー便利ですねー。


つーか、「Hello World!」やんないとか言っておきながら、、、


長くなったのでここから一気です。
各ファイルを以下の様に修正、及び新規作成します。
apps/myapp/modules/mymodule/actions/actions.class.php

<?php

/**
 * mymodule actions.
 *
 * @package    myproject
 * @subpackage mymodule
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
 */
class mymoduleActions extends sfActions
{
  /**
   * Executes index action
   *
   */
  public function executeIndex()
  {
    //$this->forward('default', 'module');
        $posts = PostPeer::doSelect(new Criteria());
        $this->posts = array();
        foreach ($posts as $post) {
                $this->posts[] = array(
                        'id' => $post->getId(),
                        'title' => $post->getTitle(),
                        'modified' => $post->getModified() ,
                );
        }
  }

  public function executeRead()
  {
    $id = (int) $this->getRequestParameter('id');
        $post = PostPeer::retrieveByPk($id);
        if ($post) {
                $this->title = $post->getTitle();
                $this->text = $post->getText();
        }
  }
  public function executeWrite()
  {
        $this->title = $this->getRequestParameter('title');
        $this->text = $this->getRequestParameter('text');
        if ( $this->title && $this->text) {
                $post = new Post();
                $post->setTitle($this->title);
                $post->setText($this->text);
                $post->save();
                $this->id = $post->getId();
        }
}


apps/myapp/modules/mymodule/templates/indexSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<table>
<tr>
<th>Title</th>
<th>Last Modified</th>
<?php foreach ($posts as $post) { ?>
        <tr>
        <td><a href='mymodule/read/id/<?php echo $post['id'] ?>'><?php echo $post['title'] ?></a></td>
        <td><?php echo $post['modified'] ?></td>
        </tr>
<?php } ?>
</table>
<h4><?php echo link_to('write','mymodule/write') ?></h4>


apps/myapp/modules/mymodule/templates/readSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<?php if (isset($title)) { ?>
<h4><?php echo $title ?></h4>
<pre>
<?php echo $text ?>
</pre>
<?php } else { ?>
<h4>Post not found</h4>
<?php } ?>


apps/myapp/modules/mymodule/templates/writeSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<?php if (isset($id)) { ?>
<h4>Post Submitted.  <a href='read/id/<?php echo $id?>'>view post</a>
<?php } else { ?>
<?php echo form_tag('mymodule/write') ?>
<table>
<tr>
        <tr>
                <td><?php echo label_for('title', 'title') ?></td><td><?php echo input_tag('title') ?></td>
        </tr>
        <tr>
                <td /><td><?php echo textarea_tag('text') ?></td>
        </tr>
        <tr>
                <td /><td><?php echo submit_tag('submit') ?></td>
        </tr>
</form>
<?php } ?>
</table>


ここまで書いたら、モジュールにアクセスしてみましょう。
ちゃんと表示されていますね。
writeから投稿画面に入って、適当に入力して登録してみて下さい。
TOPに戻ると、登録した内容がちゃんと表示されているはずです。


一気に書いた内容も特に難しい事はないですよね?読めば何となくは意味がつかめるはずです。


1つ言わせてもらうと、DBクラスは素晴らしいですね。ここまで簡素化してるなんて。ZendFrameworkよりも、シンプルで分かりやすい。ここまで可読性が高いのにやってることはとっても高度な感じします。まぁあくまで、基本的な動作を見ただけの感想ですが。

これで見事ブログみたいな投稿機能が実装されました。
「こんな簡単にできるの!?」と思うか、「これだけやって、たったこんだけの内容!?」って思うかは人それぞれですが、symfonyのすごさはまだまだここからだったりします。

次回はこれをベースに高機能ブログモジュールを作っていきます!

次回、symfony実践編パート3。You can advance?

お楽しみに。


※この記事は、私の大嫌いなIBM様の「PHPフレームワーク」の連載を大いに参考にさせて頂いています。
http://www.ibm.com/developerworks/jp/views/opensource/libraryview.jsp?search_by=PHP+フレームワーク
symfonyのヴァージョンも変わってるせいか、ぼろぼろなのであまり見る価値ないかもです。