PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1
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/にアクセス・・・
こんな画面になるはずです。

最初の作業はこの画面に書いてある通りです。
まず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'; //コメントアウトを外します
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を触ってみたよ – その1 | We’ve … PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1 | We’ve only just begun [...]
[...] 【PHP5.3を活用したフレームワークのLithiumのチュートリアル】 【変化の時(Nate AbeleがCakePHPプロジェクトから離脱してLithiumを立ち上げた理由)】 【複雑なCakePHPテンプレートのファイルパスが一目瞭然。Viewpath Pluginの紹介】 今の仕事で、開発に関するスキルが自分に足りないことを実感しまくりなので、 こーゆー記事はちょっと刺激的で楽しい。 カテゴリー: IT タグ: cakephp, Lithium, アプリ, メモ この投稿のパーマリンク ← さよなら、ホコリさん [...]
[...] PHP5.3を活用したフレームワークのLithiumを触ってみたよ – その1 [...]