slimでpimpleを使ってroutingを行う
pimpleを使ってslimのroutingを構造化してみます。
routes.phpの作成
configディレクトリを作成し、routing情報を記述するroutes.phpを作成します。
$ mkdir config $ vi config/routes.php <?php $app->get('/', function() use ($container) { $container['ContentsController']->top(); });
ContentsControllerクラスの作成
index.phpのcontrollerの中に記述していた処理をContentsControllerクラスとして独立させます。
topメソッドの中にcontroller処理を記述してます。
$ mkdir src/Taka512/Controllers $ vi src/Taka512/Controllers/ContentsController.php <?php namespace Taka512\Controllers; class ContentsController { protected $app; protected $service; public function __construct(\Pimple $di) { $this->app = $di['app']; $this->init($di); } public function init(\Pimple $di) { $this->service = $di['NameService']; } public function top() { $name = $this->service->getName(); $this->app->render('index.html.twig', array('name' => $name)); } }
index.phpを修正
controller処理を削除してroutes.phpの読み込み処理を追加します。
$ vi web/index.php 9 define('PROJECT_DIR', dirname(__FILE__) . '/..'); 10 $app = new Slim(array( ~略~ 20 $container = new Pimple(); 21 $container['app'] = $app; 22 $container['NameService'] = $container->share(function ($container) { 23 return new \Taka512\Services\NameService($container); 24 }); 25 26 $container['ContentsController'] = $container->share(function ($container) { 27 return new \Taka512\Controllers\ContentsController($container); 28 }); 29 30 require PROJECT_DIR.'/config/routes.php'; 31 32 $app->run();
これでroutes.phpにrouting情報を定義してControllerクラスをモリモリ書いていけるようになりました。
今回の作業をした後のディレクトリ構造は下記となります。
|-- composer.json |-- composer.lock |-- logs | |-- 2013-06-29.log |-- templates | |-- index.html.twig |-- config | |-- routes.php |-- vendor |-- web | |-- index.php |-- src | |-- Taka512 | |-- Controllers | |-- ContentsController.php | |-- Services | |-- NameService.php
参考
http://nesbot.com/2012/11/5/lazy-loading-slim-controllers-using-pimple
slimでネームスペースを利用するように修正
プロジェクトディレクトリの構造化を行っていきます。
今回は前回index.phpに作成したNameServiceクラスをファイルから分離して、ネームスペースを利用するように修正します。
composer.jsonの修正
autoloadの項目を追加します。srcが設定ディレクトリで「Taka512」ネームスペースとなります。
$ vi composer.json "require": { "slim/slim": "2.*", "slim/extras": "2.0.*", "twig/twig": "1.*", "pimple/pimple": "1.0.0" }, "autoload": { "psr-0": { "Taka512": "src/"} } $ php composer.phar update
ディレクトリの作成
先ほどautoloadで設定したディレクトリを作成します。
$ mkdir -p src/Taka512/Services
NameServiceライブラリの作成
NameServiceクラスをファイルに分離します。今回の例ではネームスペースは「Taka512\Services」となります。
constructのPimpleの前に「\」マークをつけるのを忘れないようにしましょう。つけないと「Taka512\Service\Pimple」を探しに行ってエラーとなります。
$ vi src/Taka512/Services/NameService.php <?php namespace Taka512\Services; class NameService { protected $di; public function __construct(\Pimple $di) { $this->di = $di; } public function getName() { return 'taka512'; } }
index.phpの修正
index.phpからNameServiceクラスを削除して、サービスの定義の部分のネームスペースを変更します。
$container['NameService'] = $container->share(function ($container) { return new \Taka512\Services\NameService($container); });
これでネームスペースを利用してライブラリをもりもり作っていけるようになりました。
slimでpimpleを使う
pimpleはphpでDIコンテナを実現するためのライブラリです。
今回はslimでpimpleを使ってみます。
インストール
composer.jsonにpimpleを追加
$ vi composer.json "require": { "slim/slim": "2.*", "slim/extras": "2.0.*", "twig/twig": "1.*", "pimple/pimple": "1.0.0" $ php composer.phar update
index.phpを編集
32~45行目でNameServiceを定義
19~23行目でNameServiceをpimpleに登録
26行目でNameServiceをpimpleから利用してます。
$ vi web/index.php 10 $app = new Slim(array( ~略~ 19 $container = new Pimple(); 20 $container['app'] = $app; 21 $container['NameService'] = $container->share(function ($container) { 22 return new NameService($container); 23 }); 25 $app->get('/', function() use ($container) { 26 $name = $container['NameService']->getName(); 27 $container['app']->render('index.html.twig', array('name' => $name)); 28 }); 29 30 $app->run(); 32 33 class NameService 34 { 35 protected $di; 36 public function __construct(Pimple $di) 37 { 38 $this->di = $di; 39 } 41 public function getName() 42 { 43 return 'taka512'; 44 } 45 }
pimpleの何が嬉しいかというとLazyロードなのでNameServiceは26行目で実際に使われるタイミングで生成されます。
slimでログを出力
前回インストールしたslim/extrasを利用してログ出力を行う設定のメモ
ログディレクトリを作成
$ mkdir -p logs $ chmod 777 logs
index.phpを編集
$app = new Slim(array( 'view' => new Twig, 'templates.path' => '../templates', 'log.writer' => new \Slim\Extras\Log\DateTimeFileWriter(array( 'path' => '../logs', 'name_format' => 'Y-m-d', 'message_format' => '%label% - %date% - %message%' )) )); $app->get('/', function() use ($app) { $app->getLog()->debug('log'); // - level 4 $app->getLog()->info('log'); // - level 3 $app->getLog()->warn('log'); // - level 2 $app->getLog()->error('log'); // - level 1 $app->getLog()->fatal('log'); // - level 0 $app->render('index.html.twig', array('name' => 'taka512')); });
index.phpにアクセスした後にログを見てみると出力されていることが確認できます。
$ tail -f logs/2013-06-29.log DEBUG - 2013-06-29T16:56:47+09:00 - log INFO - 2013-06-29T16:56:47+09:00 - log WARN - 2013-06-29T16:56:47+09:00 - log ERROR - 2013-06-29T16:56:47+09:00 - log FATAL - 2013-06-29T16:56:47+09:00 - log
今回の作業をした後のディレクトリ構造はこんな感じとなります。
|-- composer.json |-- composer.lock |-- logs | |-- 2013-06-29.log |-- templates | |-- index.html.twig |-- vendor |-- web |-- index.php
slimでtwig連携
最近slimを使う機会がありそうなのでphpのマイクロフレームワークであるslimを基礎から触った。
まずはインストールしてslimとtwigで連携するところまで行う。
composerからのslimのインストール
$ curl -s http://getcomposer.org/installer | php $ vi composer.json { "require": { "slim/slim": "2.*", "slim/extras": "2.0.*", "twig/twig": "1.*" } } $ php composer.phar install
index.phpの作成
$ mkdir web $ vi web/index.php <?php require '../vendor/autoload.php'; use Slim\Slim; use Slim\Extras\Views\Twig as Twig; $app = new Slim(array( 'view' => new Twig, 'templates.path' => '../templates' )); $app->get('/', function() use ($app) { $app->render('index.html.twig', array('name' => 'taka512')); }); $app->run();
templateを作成
$ mkdir templates $ vi templates/index.html.twig hello {{ name }}
これでindex.phpにアクセスするとテンプレートの内容が表示されます。
そして今回のディレクトリ構造はこんな感じとなります。
|-- composer.json |-- composer.lock |-- templates | |-- index.html.twig |-- vendor |-- web |-- index.php
cookpad開発コンテスト24に参加してみた。
6/15(土)に第4回cookpad開発コンテスト24に参加して応募してみました。
結果は箸にも棒にもかからなかったのですが、提出までこぎ着けたのは有意義な経験だったので感想がてら振り返ってみました。
提出ソース
https://github.com/taka512/symfony_cookpad_dev4
提出サービス
http://cookpaddev4.taka512.net
1. 準備
前日までにプロビジョニング等の準備をしました。
構成は前回のブログで書いた構成でsymfony2 + mongod + mysql + memcached+(S
3+SES)構成でawsに環境を構築しました。
この時はまだ「位置情報」、「画像アップロード」ぐらい利用しようかなーぐらいなふわふわした考えでした。
2. 序盤(11:00〜)
9:00にお題の発表だったのですが、いきなりの寝坊ww
11:00ぐらいに目が覚めてお題を確認すると、「年をとった自分が使うサービス」という事で風呂に入りながら考え始める。
「老後 幸福」とかで検索したりでゼロから検討しました。結局、自分の老後で気になるのはお金かな!と思ったので細部はつめないで毎月の収入・支出を入力していくと定年後の月収を計算する家計簿的なサービスを構想しました。
3. 中盤(18:00~)
とりあえず認証機能とbootstrapを組み込んでみたら夜になっていて少し焦りだすw
この時点で当初の作りたいなーと考えていたフル機能はあきらめる。
とりあえず、1機能でも良いので実装して最低提出できる状態にする事を目指し始めました。
4. 終盤(3:00~)
眠くなってきて、どうせ駄目だし提出しなくても良いんじゃねとか悪魔の囁きが聞こえ始める。
後半は作業も雑になってきたので、この時間帯での機能追加は厳しい感じでした。
ただ、提出はしたいというモチベーションはあったので朝7:00ぐらいに作り上げて提出完了。
そのまま就寝
5. 結果
しょぼくても、やっぱり結果発表のページを開くのはドキドキしました。
結果についてはさらっと全提出サービス見てみましたがわりと納得な感じです。1位の作品は自分が時間をかけても作れる気がしませんでしたが2位以下はアイデア次第でなんとかなりそうな気もしたので自分の企画力の無さを痛感。
6. 感想(振り返り)
途中で外出したり集中力が途切れたりで、正味10時間ぐらいは頑張ったと思います。
反省点が多いですね。次回があったら反省を生かしていきたいですねw
・よかった点
- 前日有給取っていたので頭がすっきりした状態だった。
- サーバの構築は前もって準備しておいてよかった。
・反省点
- 日頃から企画力を鍛えてなかったので構想通り実現しても微妙なサービスとなった。
- 0から作る事が久しぶりだったので、まごついてスピード感を持って作成できなかった。
- 認証機能・bootstrap組込・ライブラリなど基礎的な機能は前もって作っておくべきだった。
- 結果的に認証機能は必要なかったので、前もって24時間で作れそうな機能を絞り込んでおくべきであった。
会社ブログ用に書いたchefのレシピをリファクタしてみた。
会社の技術ブログで「vagrant + chef + serverspecを使った~」みたいな記事を書きました。
その際のchefのレシピはいくつか問題点があると思ってます。
今回はその問題点を解消すべくリファクタしてみた!っていうお話です。
会社ブログの記事
http://tech.voyagegroup.com/archives/7141452.html
会社ブログのchefのレシピ(リファクタ前)
https://github.com/taka512/techblog20130523/tree/master/chef
リファクタしたchefのレシピ(リファクタ後)
https://github.com/taka512/chef-develop/tree/myblog20130620
問題点
- バックエンド回りのパッケージがインストールされていない
- symfonyレシピにすべてを記述している
- 内部でディレクトリ名、ユーザ名など可変であるべき値をベタ書いている
問題点1 バックエンド回りパッケージのインストール
mysql、memcached、mongodbのインストールレシピを追加しました。
パッケージのインストールとサービス起動設定のみを行っております。mongodbは以下のように10genのレポジトリを追加してそこからインストールしています。
問題点2 symfonyレシピの分割
会社ブログのレシピでは時間的に動作させるのが精一杯だったので「旧symfonyレシピ」で一括して以下の事を行っていたのを分割しました。
処理 | 分割後receipt | |
---|---|---|
1 | sshの設定 | server |
2 | ntpの設定 | server |
3 | iptableの設定 | server |
4 | ユーザの追加・ディレクトリの作成 | server |
5 | nginxのインストールと設定 | nginx |
6 | パッケージのインストール | server |
7 | symfonyのインストール | symfony |
8 | アプリケーションディレクトリ | symfony |
問題点3 attributeの追加
変更前のレシピでは、ユーザ名等をベタ書きしていたため、値を変更しようとしても複数の箇所を書き換える必要がありました。chefでは値を変数として扱うattribute機能がありますのでattribute化しました。
例えば以下のようにnode/xxxx.jsonに記述する事で
こんな感じに利用する事ができます。
次回はこのレシピを使って何をやったかを書きます!