PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1

Lithium

Lithiumはphp5.3の機能をバリバリ使った新しいフレームワークです。
これまでぼくは、5.3の機能?何それ?
という感じだったので、勉強にもなるかなと思い色々触ってみました。

ということで、まず、チュートリアルをやったまとめです。


1.lithium実行環境の用意

事前に用意する環境
・php5.3
・mysql5
OSはMacOS Xで試しました。

lithium自体は、gitで簡単に設置できます。
↓からlithiumの公式サイトにユーザ登録して、git cloneで入手します。

http://rad-dev.org/users/add

今回はDocumentRootが/sitesであると仮定して、/sites/lithiumに設置します。

# cd /sites
# git clone code@rad-dev.org:lithium.git

(/sites/lithiumができる)

2.基本部分作成

li3コマンドというものが用意されていて、実行すれば基本のファイルがすぐ作れます。
cakephpで言うとbakeコマンドですね。

# cd /sites/lithium
# /sites/lithium/libraries/lithium/console/li3 library extract blog

これで、/sites/lithium/blogが作成されていると思います。

なんで3なのかは色々理由があるみたいですよ。
詳しくはコチラ
li3コマンドはpathを通しておくと便利です。

これは、
lithium/libraries/lithium/console/command/create/template/app.phar.gz
というのを展開してくれるみたいなんですが、このPharってのはjavaでいうjarみたいなもんで、
詳しくはコチラ

今回は/sites/lithium/blogというpathに作成していますが、
/sites/blogという場所にする場合は、
blog/config/bootstrap.php line15:

define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)) . '/libraries');

define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)) . '/lithium/libraries');

に変更すればいいと思います。

3.最初の作業

では

http://localhost/lithium/blog/

にアクセスしてみます。
ギャー!エラー出てるよ!
大丈夫だ、問題ない。
blog/config/bootstrap/libraries.phpで読み込んでいるlithium/net/http/Message.phpは
/lithium/net/Message.phpを必要とするので、それを足してあげます。

blog/config/bootstrap/libraries.php line23:

require LITHIUM_LIBRARY_PATH . '/lithium/core/Environment.php';
require LITHIUM_LIBRARY_PATH . '/lithium/net/Message.php'; //←足す
require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Message.php';

では再度http://localhost/lithium/blog/にアクセス・・・
こんな画面になるはずです。
step1

最初の作業はこの画面に書いてある通りです。

まずresourcesの権限を変更します。

# chmod -R 0777 /sites/lithium/blog/resources

resourcesの中にはlogとかcacheとか変換されたtemplateファイルとかが入ります。

次に、自分の環境に合わせてデータベースの設定を書きます。
今回はMySQL上にli3_testというデータベースを作って使っています。

DB設定の追加は以下のように書きます。
blog/config/connections.php

<?php
/**
 * Lithium: the most rad php framework
 *
 * @copyright     Copyright 2010, Union of RAD (http://union-of-rad.org)
 * @license       http://opensource.org/licenses/bsd-license.php The BSD License
 */
use \lithium\data\Connections;

Connections::add('default', array(
	'type' => 'database',
	'adapter' => 'MySql',
	'host' => 'localhost',
	'login' => 'root',
	'password' => 'password',
	'database' => 'li3_blog'
));
?>


続いて、コメントアウトを外してconnections.phpを読み込みます。
config/bootstrap/bootstrap.php line46:

require __DIR__ . '/connections.php';  //コメントアウトを外します

両方やって↓みたいに緑色に変わればオッケーです!
step2

4.テーブルを作る

今回は以下のテーブルを使用しました。

CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `body` text COLLATE utf8_unicode_ci NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;


5.下地を作る

またまた登場li3コマンド。
Postsというコントローラ、モデルを作ります。
コントローラ、モデルって何?!って人はコチラ

# cd /sites/lithium/blog
# li3 create Posts
Post created in app\models.
PostsController created in app\controllers.
PostTest created in app\tests\cases\models.
PostsControllerTest created in app\tests\cases\controllers.

これで、blog/内にmodel,controller,testが用意されます。

ではcontrollerのファイルの各メソッドを見てみます。

	public function index() {
		$posts = Post::all();
		return compact('posts');
	}

$postsにPostモデルの全件検索結果を入れています。
cakephpでは$Post->find(‘all’)とかやってた部分です。
lithiumはほぼstaticで書かれていて、LSB(遅延静的束縛)を利用したコードになっているようです。
この辺の利点とかはちょっと難しくてまだわかっていません。。。(誰か教えて!)
$postsはRecordSetオブジェクト(インスタンス)になります。
viewで使いたいものをreturnで返してやります。

	public function view() {
		$post = Post::first($this->request->id);
		return compact('post');
	}

Postモデルから、最初に一致するレコードを取得します。
ここでの$postはRecordオブジェクトになります。

	public function add() {
		$post = Post::create();

		if (($this->request->data) && $post->save($this->request->data)) {
			$this->redirect(array('Posts::view', 'args' => array($post->id)));
		}
		return compact('post');
	}

$postにRecordオブジェクトを作って、$post->save()で保存しています。
$this->requestはリクエスト内容が保持されているlithium\action\Requestオブジェクトが入っています。
$this->request->dataにformのデータが入っています。
cakephpで言うと$this->paramsとして使えるものは$this->request->paramsです。
他にはcontroller名、action名、その他の引数、formのデータ、HTTPヘッダ、サーバ環境などが入っているようです。
後述しますが、名前付きパラメータ(idとか)は$this->request->idとしてアクセスできます。
実際にはprotectedの$_idという値を__get(マジックメソッド)で取得しています。
$this->request->idの値がない場合、nullが返るようです。

	public function edit() {
		$post = Post::find($this->request->id);

		if (!$post) {
			$this->redirect('Posts::index');
		}
		if (($this->request->data) && $post->save($this->request->data)) {
			$this->redirect(array('Posts::view', 'args' => array($post->id)));
		}
		return compact('post');
	}

Postモデルのfindメソッドを実行しています。
$this->redirect()で、リダイレクトさせることができます。
リダイレクト先のURLはController::actionという形で記述できます。
argsにarrayを入れると、順番にくっついて

http://yourdomain/posts/view/arg1/arg2/arg3…という感じになります。


6.viewを作る

viewのファイルはないので、自分で書きます。
ファイル名はblog/views/controller名/action名.html.phpになります。

まずはindexのview。
blog/views/posts/index.html.php

<?php foreach ($posts as $post): ?>
	<p><?=$post->title; ?></p>
	<p><?=$post->body; ?></p>
	<p>
		<?=$this->html->link('Edit', array('Posts::edit', 'id' => $post->id)); ?>
		<?=$this->html->link('View', array('Posts::view', 'id' => $post->id)); ?>
	</p>
	<hr>
<?php endforeach ?>

まずphpのショートタグのようなものが目にとまると思います。
lithiumは、<?= ?>で囲まれた部分を自動的にphpタグ+echo+htmlタグのエスケープをするように書き換えますので、ショートタグではありません。

$this->htmlはcakephpではおなじみのHtmlヘルパーです。
link意外にも色々なメソッドが用意されています。
$this->html->link(リンク文字列, リンクURL)という書き方ですが、
URLはController::actionという形で記述できます。
こういう書き方もできます。

<?=$this->html->link('View2', array('controller' => 'posts', 'action' => 'view', 'id' => $post->id)); ?>

foreachでまわっている$postsは
lithium\data\collection\RecordSetのオブジェクトのインスタンスになっています。
これは、lithium\data\entity\Recordのセットになっていて、
\ArrayAccess, \Iterator, \Countableのインターフェースを持つlithium\util\Collectionを継承しています。
そのため、arrayとしてアクセスしたりforeachで展開したりcount関数でカウントしたりできます。
この辺はphpマニュアルの「定義済みのインターフェイス」とか「SPLインターフェイス」とかを読むといいと思います。
あとは先日発売したWEB+DB PRESS Vol.59 にとてもわかりやすく書かれていましたので、
読むことをオススメします!

続いてaddのview。
blog/views/posts/add.html.php

<?=$this->form->create($post); ?>
     <?=$this->form->field('title'); ?>
     <?=$this->form->field('body'); ?>
     <?=$this->form->submit('Save'); ?>
<?=$this->form->end(); ?>

Formヘルパーを使ってフォームを作成しています。
createでformタグ開始、、field()でinputを作って、submitでsubmitボタンを作って、
end()でformタグを閉じる、という感じです。

これがviewのview(ビューのビュー・・・)です。
blog/views/posts/view.html.php

<h3><?=$post->title; ?></h1>
<p><?=$post->body; ?></p>
<p><?=$this->html->link('Edit', array('Posts::edit', 'id' => $post->id)); ?></p>


今回はedit.html.phpは作りません。
addと同じフォームを使えばいいので、addと同じviewファイルを使うようにしちゃいましょう。

editアクションに1行追加します。
blog/controllers/PostsController.php line28:

	public function edit() {
		$this->_render['template'] = 'add';  //ここを追加したよ!
		$post = Post::find($this->request->id);

		if (!$post) {
			$this->redirect('Posts::index');
		}
		if (($this->request->data) && $post->save($this->request->data)) {
			$this->redirect(array('Posts::view', 'args' => array($post->id)));
		}
		return compact('post');
	}


8.メニューが欲しい

これでindex,add,editが動くようになったんですが、
移動しやすいように簡易メニューをつけちゃいましょう。
いろいろな場所で使うものはelementで作って読み込むようにできるので、
なんとなくノリでelementで作ってみます。

以下のファイルを作成します。
blog/views/elements/menu.html.php

<p>
	<?=$this->html->link('Index', 'Posts::index'); ?>
	<?=$this->html->link('Add', 'Posts::add'); ?>
</p>
<hr>


elementファイルを作ったら、div id=headerの場所に入れちゃいます。
blog/views/layout/default.html.php

			<h2>
				Powered by <?php echo $this->html->link('Lithium', 'http://li3.rad-dev.org'); ?>.
			</h2>
			<?=$this->view()->render(array('element' => 'menu')); ?>

$this->view()->render(array(‘element’ => ‘エレメント名’));
これでelementをそこへ読み込めます。
言い忘れてましたが、デフォルトではblog/views/layout/default.html.phpが読み込まれて
表示されるようになっています。
これを変えたい場合は、Controllerのaction内などで
$this->_render['layout'] = ‘layout名’;
と書けば、layout名.html.phpが代わりに読み込まれます。

9.deleteアクションを作る

そういえばdeleteがない!ということで作ります。
Postsコントローラにdeleteアクションを追加しましょう。

blog/controllers/PostsController.php

	public function delete() {
		$post = Post::find($this->request->id);

		if ($post && $post->delete()) {
			$this->redirect('Posts::index');
		} else {
			$this->redirect('Posts::index');
		}
	}

Modelからfindして取得したオブジェクトのdeleteメソッドで、該当のレコードが削除されます。
でもこれでは、成功しても失敗しても同じですね・・・。
というわけでライブラリを使って、成功・失敗のメッセージを出したいと思います。

が、長くなりそうなので今回はここまで。

次以降の内容は、
・かつお、ライブラリを使う
・わかめ、validationする
・波平とBehavior
の3本です。
下書きしかまだしてないので、頑張って書きます!

それと、この記事(+この後の記事)を書くにあたって以下のサイトがとても参考になりました。
書いてくれた人ありがとうございます!

lithium blog tutorial
lithium photoblog tutorial
The longer Lithium Blog tutorial using MySQL – Part 1
Lithiumのフィルタシステム

あとがき

こんだけ書くだけでも大変ですね・・・
いつも記事をアップしている人達を尊敬しました。

このエントリーを含むはてなブックマークはてなブックマーク - PHP5.3を活用したフレームワークのLithiumを触ってみたよ &#8211; その1 この記事をクリップ!Livedoorクリップ - PHP5.3を活用したフレームワークのLithiumを触ってみたよ &#8211; その1 Yahoo!ブックマークに登録 このエントリをつぶやくこのWebページのtweets Bookmark this on Delicious
Posted By nano_eight

3 Responses to “PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1”

  1. [...] PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1 | We’ve … PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1 | We’ve only just begun [...]

  2. [...] 【PHP5.3を活用したフレームワークのLithiumのチュートリアル】 【変化の時(Nate AbeleがCakePHPプロジェクトから離脱してLithiumを立ち上げた理由)】 【複雑なCakePHPテンプレートのファイルパスが一目瞭然。Viewpath Pluginの紹介】 今の仕事で、開発に関するスキルが自分に足りないことを実感しまくりなので、 こーゆー記事はちょっと刺激的で楽しい。 カテゴリー: IT   タグ: cakephp, Lithium, アプリ, メモ   この投稿のパーマリンク ← さよなら、ホコリさん [...]

  3. [...] PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1 [...]

Leave a Reply