Fukuoka.php Vol.14 で喋ってきました
ブログを書くまでが勉強会です。
当日喋ったスライドはこちら。
今年のPHPカンファレンスですが、福岡から参加した人はあまり多くなかったようで、こんな話があってめっちゃ楽しかったよ!というと、PHPはどんどん進化してるので未来は明るいし、僕らも継続して学んでいくことで、もっとうまくPHPを扱えるようになろう!のが少しでも伝わればよいなぁと。
で、こっちが PHP5.6 の話。地味だけどなかなかよい改善がされてます。で、PHP5.6 では実務的にどういった変化が起こるのか?という視点でお話させていただきました。スライドにも書いてますが、定数でスカラー式が扱えること、定数/関数で名前空間を扱えること。可変長引数の登場で3つの関数がオワコンになるんじゃないの?と。
- define
- func_get_args
- function_exists
ですね。
他の方の発表の感想
これからのCMSマーケットトレンドとPHP by @ takufujita
これからのCMSマーケットトレンドとPHP (for fukuoka.php)
"エンプラCMS" というのを初めて知ってあまりの高機能っぷりにびっくりした。テンプレートの管理やテンプレートのブロックもバージョンを持てるようになってたり、マーケティング的な機能も入ってたりしてる。
僕最近 CMS に興味持てなくなってて、あまりウォッチしてなかったんですが、エンプラCMSに俄然興味が沸いてきました。弄りがいがありそう。
自己紹介 by @murasakipinko
PHP Woman Fukuoka だと…!?
— MATSUO Masaru (@localdisk) 2014, 10月 17
PHP Women Fukuoka よいと思う #fukuokaphp
— MATSUO Masaru (@localdisk) October 17, 2014
多分 JS Girls 的なアレだと思います。楽しみですね!
LT
懇親会
AM4時までありました。非常に愉快でした。
PHP カンファレンス 2014 に行ってきました
10/11 に行われた PHPカンファレンス2014 に行ってきました。
僕は打ち合わせがあったので前日入りして、夜は Laravel 好きの皆さんと飲み会しました。
参加メンバー
- @kurikazu
- 幹事あざっした!オサレなお店でデートで来たらいいだろうなーと思いました。
- 飲んだお店。炙屋小鉄
- あと優先LANアダプタ貸していただいてありがとうございます!
- @syossan27
- 飲み会中に彼女持ちということが発覚。たっぷり悪態をつきました。
- @ex_takezawa
- Yahoo!JAPAN への転職おめでとうございます。
- @blue_goheimochi
- 障害対応で来れなかった人
- PHP カンファレンスには徹夜明けで来てた
- ほんとおつかれさまでした…ご挨拶できて良かったです
ここからPHPカンファレンス本番。二日酔い気味でしたがちゃんと基調講演から聞きました。
では、セッション等の感想をば。
基調講演
PHPカンファレンス皆勤のひろかわさん。
- PHP 5.6 は地道な改善が行われた
- HHVM の登場
HHVM の登場で本家に火がついたというはあるよなー #phpcon2014
— MATSUO Masaru (@localdisk) 2014, 10月 11
- PHP 7
- PHP 6 はスキップ。PHP 7が楽しみ。順調に行けば来年のPHPカンファレンスくらいにはリリースしてるかも?
PHPコアから読み解くPHP5.5
- Yahoo! JAPAN のこもいけさん
PHPコアから読み解くPHP5.5 を聞いてる。こもいけさんの喋りがなんとなくつぶやきシローを彷彿とさせる。 #phpcon2014
— MATSUO Masaru (@localdisk) 2014, 10月 11- あとのセッションに PHPにおけるI/O多重化とyield というのがあって、これも Yahoo! JAPAN の @hiraku さんの発表。Yahoo! JAPAN では空前の yield ブームが来ているのかもしれない
- zend_execute からのくだりは「なるほど、わからん」としか言いようがなかった。こもいけさんがどうこうではなく、僕の理解力の問題です。
ブースを見て回ったよ
2コマほど集中力全開で聞いてたら頭が沸騰してきたのでブースをみてまわることに。色々みてまわりました。
ブースで貰えるよ! #phpcon2014 pic.twitter.com/FlicmEfJm9
— MATSUO Masaru (@localdisk) 2014, 10月 11
ツイートしたらタオルあげる!と言われたので律儀にツイートしてます。
印象に残ってるブースを3 + 1 .
Unity ブース
Oculus Rift と連動させてて、ちょう空いてたので見せてもらいました。すげぇ…俺、もう、2次元に住んじゃうよ…と思った。
EC Cube ブース
高橋さんとお話させていただいた。どうも EC Cube はリライトする予定らしいです。色々計画している模様。楽しみです。Laravel をベースにしたら全力でコントリビュートする所存。
BASE ブース
(生えふしんだ!生えふしんだ!)ってなってた。
BASE Developersを作ったというのとBASE SECURITY CHALLENGEとのこと。
アシアルブース
誰もいなかった…@anatooさんに挨拶したかったのと Monaca について聞いてみたかった。残念
あとはteratail【テラテイル】|思考するエンジニアのためのQAプラットフォームを運営しているレバレジーズのブースなどにお邪魔しました。Laravel の質問に答えてるのは僕ですと自己紹介しました。
PHPにおけるI/O多重化とyield
ここからセッションに復帰。またもや yield の話。
HHVM + Hack == PHP++
本日のメインイベント。発表者の Paul さんも素晴らしかったし、翻訳した方も同じくらい素晴らしかった。HPHPc があえなく死んでしまった…という話でぐっと観衆の心を掴んでそこからはもう怒涛の如くという感じ。ちょっとまだ個人的に興奮が収まってなくてうまく言語化できないのでPHPカンファレンス2014でHHVM/Hackの話を聞いて感動した - As a Futurist...を参考にしてください。
途中からですが、Ustream で動画も見れるみたいです。
Ustream.tv: ユーザー phpstudy: phpcon2014-main, phpcon2014-main. コンピュータ
「日本では CentOS が人気なんだけど HHVM はバイナリを提供する予定はあるか?」という質問に「CentOS はつらい」回答しているところがもうたまりませんでした。
LT CMS/DB
途中までなんかフラフラしてました。まともに聞いたのは「LT CMS/DB PHP&NewSQL;で考える次世代アプリケーション」で夢あふれるセッション。フィットしそうな案件があったら試してみたい。
LT無差別級
どれも素晴らしいLTでした。残念なのが5分で収まらないものが多く「最後まで聞かせてくれ!頼むから!」という感じなのでした。ドラは無慈悲だ。
懇親会 + LT
LT 募集ということなので、Laravel5 のことを喋らせて頂いた。が、時間が足りず言いたいことが半分も言えず非常に残念。@ex_takezawa がネット環境を貸してくれて助かりました。ありがとうございます!
懇親会では @uzulla さんにお会いできたのが嬉しかった。色々とお話できました。にしし。@tanakahisateruのガンダムLTが素晴らしかった。あと、何故か司会をしてた @shin1x1と@msngお疲れ様でした。
打ち上げ
懇親会が終わった後は関西勢と一緒にレバー食べたり中華食べたりお酒飲んだりしました。途中から@yohgakiさんともご一緒させていただきました。楽しかったなー。
まとめ
いやぁ、この2日間はリア充といっても過言ではない!というかこの2日間びっくりするくらい楽しかったので来てよかったとおもいました。次回は 2015/10/3 とのことで今から楽しみです。PHPカンファレンススタッフに感謝感謝、そして僕の話し相手になってくれた方にも感謝。
ではまた来年!!
PHPカンファレンス行ってきます
今週土曜日 (10/11) に PHPカンファレンス2014 が開催されます。実のところ初参加でして、楽しみ半分不安半分といったところです。
"ぼっちになっても泣かない" を目標に楽しみたい所存です。
当日見ようと思っているプログラムはこちら。
- 基調講演
- 基本。
- PHPコアから読み解くPHP5.5
- 面白そう。PHP5.6の話もあるといいなー。
- フリマアプリ「メルカリ」の超高速開発を支える PHP
- ここは迷ってて、もしかしたら「mysqlnd 徹底解説」に行くかも。
- PHPにおけるI/O多重化とyield
- もしかしたらお昼ごはん食べてるかもしれません。
- HHVM + Hack == PHP++
- 通訳ありなのが助かります。一番楽しみにしてるセッション。2番めに楽しみな「Good Parts of PHP and The UNIX Philosophy」が聞けないのが残念…。
- 休憩
- 14:50 - 15:20は特にこれはというものはなし。「PHP&NewSQLで考える次世代アプリケーション」だけ気になってるのでこれだけは聞く予定。
- LT
- 楽しみにしてるのは、「PHPでAIプログラミングコンテスト準優勝するまでの軌跡」と「良いことも悪いこともぜんぶPHPが教えてくれた」と「PHPNGの現状を知る」と「中年以降エンジニアの成長戦略」
以上。楽しみだ!
Laravel 5 はこう変わる! メソッドインジェクションとFormRequest編
注意!
このエントリは 2014/09/30 時点の情報です。これからどんどん変わっていく可能性があるので鵜呑みはダメ、絶対。
はじめに
11月にリリースされる Laravel5 の変更点を説明していきます。前回は
Laravel4 では存在しなかった FormRequest
とメソッドインジェクションについて説明します。個人的には一番の目玉です。
メソッドインジェクション
Laravel4 にもあった Ioc コンテナは今までコンスタラクタインジェクションしかできませんでした。
<?php class HomeController extends Controller { /** * User * * @var \App\User */ private $user; /** * コンストラクタインジェクション */ public function __construct(User $user) { $this->user = $user; } }
Laravel5 ではメソッドインジェクションが可能になったのでこうかけるようになりました。
<?php class HomeController extends Controller { public function index(User $user) { // インジェクションされてる! dd($user); }
これは嬉しい変更ですね。助かります。
FormRequest
さて、メソッドインジェクションを踏まえて FormRequest の説明をします。FormRequest
は既存の Request
クラス(Laravel4 でいうところの Input + Request クラス)にValidationと認証機能(?)を足したものです。
まずは作ってみましょう。
php artisan make:request App\\Http\\Requests\\HomeRequest
ポイントは名前空間を \\
で区切ってやるのがポイントです。ここらへん以前は(3日前くらい)は名前空間を付ける必要がなかったのですが、現時点では必要です。もしかしたらいらなくなるかもしれません(Laracasts を収録した段階では必要なかった模様)。すると app/Http/Requests
にこんな感じのファイルが出来上がります。
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class HomeRequest extends FormRequest { /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ // ]; } /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return false; } }
rules
メソッドと authorize
が実装されています。rules
は Validaiton ルールを書く場所です。
<?php /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required', 'email' => 'required|email', 'password' => 'required|min:8', ]; }
こんな感じに書いて…コントローラーにインジェクションすると、Validation が自動に実行されます。Validation がうまく行かなかった時はデフォルトで前画面に戻ります。挙動を変えたい場合は FormRequest
の redirect
フィールドを定義してください。細かい挙動は Illuminate\Foundation\Http\FormRequest#getRedirectUrl
を参照してください
<?php public function store(HomeRequest $request) { dd($request->all()); }
今までは Controller に書いたり Ardent のように Eloquent
のメソッドをオーバーライドして Model 側で Validation を実行させたりしていましたが、この変更で決着をみたんじゃないかと思います。
Validaitonの必要がない場合は \Illuminate\Http\Request
をインジェクションするのもありですね。
<?php public function store(Illuminate\Http\Request $request) { dd($request->all()); }
でも、これルートパラメータと相性悪いかもしれませんね。調査しきれていないので解決方法があるかもしれませんが。
で次の、authorize
メソッドなんですが、これイマイチどう使えばいいかわかってません。 認証されたかどうかのチェックなら AuthFilter
使えばいいしなぁ…。一応説明するとこのメソッドで false
を返すと 403 が返却されます。 true
を返すと次の処理へ進みます。forbiddenResponse
をオーバーライドすることで挙動を変えることができます。
終わりに
ちょっと長めになりましたが、Validation の手間が大幅に軽減されたのは嬉しい限りです。リリースが楽しみですね。
次回は新たに追加された ServiceProvider
の話か、route:cache の話をしたいと思います。
Laravel 5 はこう変わる! ディレクトリ構造編
注意!
このエントリは 2014/09/30 時点の情報です。これからどんどん変わっていく可能性があるので鵜呑みはダメ、絶対。
はじめに
Laravel 5 は現在絶賛開発中で現行の 4.2.9 と比較するとかなり大きく変更されます。11月にリリース予定ですが、その前に先取りして主な変更点を何回かにわけてブログに書き残しておこうと思います。
一応 PHP カンファレンスが始まる前には書き終わりたいと思っていますが、我慢できない人は What's New in Laravel 5.0 のスクリーンキャストを見るとよくわかります。
Laravel5 のインストール
Composer でインストールできます。
composer create-project laravel/laravel forder-name dev-develop
ディレクトリ構造
かなり変わりました。軽く解説していきます。tree 構造はこちら。
root. ├── app │ ├── Console │ ├── Http │ │ ├── Controllers │ │ ├── Filters │ │ └── Requests │ └── Providers ├── bootstrap ├── config │ ├── local │ ├── packages │ └── testing ├── database │ ├── migrations │ └── seeds ├── public │ └── packages ├── resources │ ├── lang │ │ └── en │ └── views │ └── emails │ └── auth ├── storage │ ├── cache │ ├── logs │ ├── meta │ ├── sessions │ ├── views │ └── work ├── tests └── vendor
Laravel4 との対比はこんな感じ。
Laravel4 | Laravel5 |
---|---|
app/commands | app/Console |
app/config | config |
app/controllers | app/Http/Controllers |
app/database | database |
app/lang | resources/lang |
app/models | app |
app/start | ない |
app/storage | storage |
app/tests | tests |
app/views | resources/virews |
app/filters.php | 廃止(app/Providers/FilterServiceProviderに定義) |
app/routes.php | app/Http/routes.php |
bootstrap | bootstrap |
public | public |
大きな変更点として app
周りがガラッと変わっています。これ、ディレクトリ構造だけではなくて Laravel4 では 自作するController/Model/Command
は名前空間の修飾を必要としませんでしたが*1 Laravel5 からは名前空間は必須となります。手数が増えるかわりに自由度が上がった感じでしょうか。個人的には歓迎しています。
個人的には Model
が app
の下にあるのがもにょりますが、自由に変更できるので、まぁいいかと。
Laravel で xhprof を手軽につかう
「推測するな。計測せよ」
と偉い人が言っていました。先人に倣って僕も頑張ろうと思います。…というのも自分が今作ってるアプリが特定の条件で極端に遅くなるという現象に遭遇したからですが。
というわけで Facebook 謹製*1 の xhprof を使ってみることにします。後継と言われている uprofiler はまだ HomeBrew ではインストールできなかったので。
PHP と xhprof のインストール
brew install php55 php55-mcrypt php55-xhprof
簡単ですね。mcrypt 入れてるのは Laravel で必要だからです。
xhprof_html/xhprof_lib を任意の場所にコピーする
mkdir $HOME/.xhprof cp /usr/local/Cellar/php55-xhprof/{なんかユニークな文字列が入る}/xhprof_html $HOME/.xhprof/xhprof_html cp /usr/local/Cellar/php55-xhprof/{なんかユニークな文字列が入る}/xhprof_lib $HOME/.xhprof/xhprof_lib
Laravel のコードに xhprof を仕込む
アプリケーションイベントを使うのが簡単でよいです。
<?php // app/start/global.php App::before(function() { // xhprof を有効にする xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY); }); // shutdown App::shutdown(function() { // 計測する $xhprof_data = xhprof_disable(); $XHPROF_ROOT = '/Users/localdisk/.xhprof'; $APP_NAME = 'app_name'; require_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_lib.php'; require_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_runs.php'; $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, $APP_NAME); // ログに xhprof 用の URL が出力されます Log::debug("http://localhost:8001/index.php?run={$run_id}&source={$APP_NAME}"); });
今回はタイトルにあるように手軽さを重視していますが、Laravel 的には Middleware
を作って ServiceProvider
に登録するのがよいと思います。設定も思いのままですし、アプリケーションのコードを修正する必要がなくなります。
あとは $HOME/.xhprof/xhprof_html
をルートにしてPHPのビルトインサーバーを起動させておき、app/storage/logs/laravel.log
に出力された URL にアクセスすればOKです。
最後に宣伝
明日 InnoCafe 開発コミュニティサミット in 福岡 - イノベーター・ジャパン | Doorkeeper という集まりがあります。東京と福岡のコミュニティについて面白い話が聞けるのでよかったら遊びに来てください。
翌日である 9/13 は ヌーラボさんのオフィスをお借りしてもくもく会をします。こちらもきっと楽しいと思いますのでよかったらどうぞ。
*1:だと思ってたけど違う人がメンテしてる?
CakePHPer のための Laravel 入門 - ブログチュートリアル2
CakePHPer のための Laravel 入門 - ブログチュートリアル1 - localdiskの続きです。
Postコントローラの作成
cake-to-laravel/app/controllers
に 投稿記事(posts)に対するコントローラを作成します。
<?php class PostController extends BaseController { }
全てのコントローラーは BaseController
クラスを拡張する必要があります*1。では、一つメソッドを作って呼び出してみましょう。
<?php class PostController extends BaseController { public function getIndex() { // URL を echo する echo Request::url(); } }
コントローラを呼び出すのにはルートの定義が必要です。cake-to-laravel/app/routes.php
を以下のように編集します。
<?php // コントローラを登録 Route::controller('posts', 'PostController');
では、http://localhost:8000/posts/index
をブラウザでアクセスしてみましょう。アクセスした URL が表示されるはずです。
次は前回作成したモデルを表示させてみましょう。コントローラを以下のように編集します。
<?php class PostController extends BaseController { public function getIndex() { return View::make('posts.index', ['posts' => Post::all()]); } }
Post ビューの作成
Post モデルの内容を表示するシンプルなビューを作りましょう。ビューの設置場所は cake-to-laravel/app/views
になります。今回はそこに posts
というフォルダを作ってその中に index.php
というファイルを作りましょう。
<h1>Blog posts</h1> <table> <tr> <th>Id</th> <th>Title</th> <th>Created</th> </tr> <!-- ここから、$posts配列をループして、投稿記事の情報を表示 --> <?php foreach ($posts as $post): ?> <tr> <td><?php echo $post->id; ?></td> <td> <!-- link_to_action を使うと定義されていなければエラーになる --> <?php echo link_to("posts/view/{$post->id}", $post->title) ?> </td> <td><?php echo $post->created_at ?></td> </tr> <?php endforeach; ?> </table>
シンプルですよね。煩わしい配列がないところが特に。
ビューの中のリンク(投稿記事のタイトルから/posts/view/some_idというURLへのリンク)をクリックすると、Laravelは、そのアクションはまだ定義されていません、エラー画面を表示します。*2
では、エラーを撲滅するべく表示用のメソッドを実装しましょう。
<?php class PostController extends BaseController { public function getIndex() { return View::make('posts.index', ['posts' => Post::all()]); } public function getView($id) { // この状態だと $id が URL に付加されてない場合は ErrorException が発生する // $id あってもなくてもよい場合は getView($id = null) とすればよい // Model::findOrFail を使うとモデルが見つからなかった場合 // ModelNotFoundException を発生させる return View::make('posts.view', Post::findOrFail($id)); } }
記事の追加
続きはあとで。
CakePHPer のための Laravel 入門 - ブログチュートリアル1
CakePHPer のための Laravel 入門 - インストール - localdisk の続き。
さて、前回はインストール、環境の設定(localに設定しました)、拡張のインストールを行いました。今回はメインである CakePHP のブログチュートリアルを Laravel で実装してみましょう。
データベースの設定
まずは、cake-to-laravel/app/config/local/database.php
を設定しましょう。前回触れましたが、Laravel は環境ごとの設定を容易に作成することができます。今回は local 環境のデータベースを SQLite を使用する設定を行います。たった一行追加するだけです。
<?php return array( 'default' => 'sqlite', // <- ここを追加! 'connections' => array( 'mysql' => array( 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'homestead', 'username' => 'homestead', 'password' => 'secret', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ), 'pgsql' => array( 'driver' => 'pgsql', 'host' => 'localhost', 'database' => 'homestead', 'username' => 'homestead', 'password' => 'secret', 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', ), ), );
これで local 環境は、SQLite を使用することになります。
マイグレーション
Laravel では、データベースのスキーマコントロールにマイグレーションを使用します。CakePHP でも同様のことができますがプラグインが必要です。まずはマイグレーションを使用できるようにするために以下のコマンドをターミナルから実行してください。
$ php artisan migrate:install
コマンドを実行したあと、以下のように表示されれば成功です。
Migration table created successfully.
テーブルの作成
マイグレーションの設定ができたら posts
テーブルを作成しましょう。ターミナルで以下のコマンドを実行してください。
$ php artisan generate:migration create_posts_table
コマンド実行すると以下のように表示されます。
Created: /Users/localdisk/NetBeansProjects/cake-to-laravel/app/database/migrations/2014_08_03_061640_create_posts_table.php Generating optimized class loader
はい、作成できましたね。ではこのファイルを覗いてみましょう。
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function(Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('posts'); } }
ちゃんと出来ていますね。では、 up
メソッドを修正しましょう。2行追加するだけです。
<?php class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function(Blueprint $table) { $table->increments('id'); $table->string('title', 50); // 追加 $table->text('body'); // 追加 $table->timestamps(); }); } }
修正したら、以下のコマンドを実行して posts
テーブルを作成します。
$ php artisan migrate
コマンド実行すると以下のように表示されます。
Migrated: 2014_08_03_061640_create_posts_table
はい、これでテーブルができました。次はモデルを作成しましょう。
Post テーブルの作成
posts
テーブルと対になる Post
モデルを作成します。ターミナルで以下のコマンドを実行してください。
$ php artisan generate:model Post
コマンド実行すると以下のように表示されます。
Migrated: 2014_08_03_061640_create_posts_table
これで Post
モデルが作成されました。
<?php class Post extends \Eloquent { protected $fillable = []; }
シード
作成した posts
テーブルに表示用の初期値を設定します。
$ php artisan generate:seed posts
コマンド実行すると以下のように表示されます。
Created: /Users/localdisk/NetBeansProjects/cake-to-laravel/app/database/seeds/PostsTableSeeder.php
これで PostsTableSeeder.php
が作成されました。では、内容を確認してみましょう。
<?php // Composer: "fzaninotto/faker": "v1.4.0" use Faker\Factory as Faker; class PostsTableSeeder extends Seeder { public function run() { $faker = Faker::create(); foreach (range(1, 10) as $index) { Post::create([ ]); } } }
生成されたファイルには Faker の記述がありますが、今回は使用しません。結構便利なライブラリなので、興味があるならぜひ使用してみてください。
では、ブログチュートリアルにそってデータを作成していきましょう。
<?php class PostsTableSeeder extends Seeder { public function run() { Post::create([ 'title' => 'タイトル', 'body' => 'これは、記事の本文です。' ]); Post::create([ 'title' => 'またタイトル', 'body' => 'そこに本文が続きます。' ]); Post::create([ 'title' => 'タイトルの逆襲', 'body' => 'こりゃ本当にわくわくする!うそ。' ]); } }
そして DatabaseSeeder.php
を以下のように修正します。
<?php class DatabaseSeeder extends Seeder { /** * データベースシード(初期値設定)を実行 * * @return void */ public function run() { Eloquent::unguard(); // PostTableSeeder を実行する $this->call('PostsTableSeeder'); } }
では、db:seed
コマンドを実行して初期値をテーブルに設定しましょう。
$ php artisan db:seed
コマンド実行すると以下のように表示されます。
Seeded: PostsTableSeeder
これでデータベースに初期値が設定されました。
続く!
CakePHPer のための Laravel 入門 - インストール
CakePHP のブログチュートリアルを Laravel で実装してみました。手順をなるだけ詳細に説明します。CakePHPer で Laravel に興味を持っている人に参考になれば幸い。
Laravel のインストール
laravelja.phar
Laravel のインストーラー phar ファイルをダウンロードします。
- @HiroKwsさんの作成したインストーラー日本語版をダウンロードします
- ターミナルで以下のコマンドを実行します。
$ php laravelja.phar new -l ja -s cake-to-laravel
- すると
cake-to-laravel
というディレクトリの下に Laravel がインストールされます。 - phar ファイルでのインストールは Composer のそれと比べて早いのと日本語化されたメッセージファイルがインストールされるのでおすすめ。
インストールされた Laravel は最新版ではない(4.2.1)ので composer update します。$ composer updateこれで 4.2.7 にバージョンアップされます (2014/08/02 現在)- 川瀬さんが対応してくれました!ブログ書いててよかった!
環境を設定する
Laravel も他のフレームワークと同じく手軽に複数の環境を扱うことができます(local / testing / staging / production) 。環境の設定は cake-to-laravel/bootstrap/start.php
内の $app->detectEnvironment
で行います。デフォルトの環境は production
です。環境はホスト名で決定します。 例外として*
は全てに当てはまります。今回は local
に設定します。cake-to-laravel/bootstrap/start.php
を以下のように設定してください。
<?php $env = $app->detectEnvironment(array( 'production' => array('production.host'), // production のホスト名 'staging' => array('staging.host'), // ステージングのホスト名 'local' => array('*'), // それ以外はローカル ));
開発中は local
に設定しておきましょう。
設定ファイルについて
Laravel の設定ファイルは app/config
にあります。この下に環境名(今回の場合は local)の名前のついたディレクトリを作成し、オーバーライドしたい同名の設定ファイルを設置することによって、環境ごとの設定を行うことができます。
必須パッケージをインストールする
以下2つのパッケージをインストールします。
- Laravel4 Generators
- Laravel IDE Helper Generator
- IDE を使っていない人は必要ありません
composer.json を編集
cake-to-laravel
の直下の composer.json
を以下のように書き換えてください。コピペでOK。
{ "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "require": { "laravel/framework": "4.2.*" }, "autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php" ] }, "require-dev": { "barryvdh/laravel-ide-helper": "1.*", "way/generators": "dev-master" }, "scripts": { "post-install-cmd": [ "php artisan clear-compiled", "php artisan optimize" ], "post-update-cmd": [ "php artisan clear-compiled", "php artisan ide-helper:generate", "php artisan optimize" ], "post-create-project-cmd": [ "php artisan key:generate" ] }, "config": { "preferred-install": "dist" }, "minimum-stability": "stable" }
app.php を編集
cake-to-laravel/app/config/app.php
の providers
の配列に以下を追加します。
<?php return array( 'providers' => array( ・・・ 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', 'Way\Generators\GeneratorsServiceProvider', ), );
ファイルを編集したら $ composer update
してください。
動作確認
では、Laravel の動作確認をしてみましょう。ターミナルで以下のコマンドを入力して下さい。
$ php artisan serve
すると
Laravel development server started on http://localhost:8000
とターミナルに表示されると思います。ブラウザから http://localhost:8000
にアクセスしてみてください。
上記画面が、ブラウザに表示されれば正常に処理されています。
続く!
Laravel の unique ルールとソフトデリート
先月中旬から東京に出張行ってるんですが、通勤のストレス*1から部屋(くっそ狭いマンスリーマンション)で勉強する気力が沸かなかったのですが、1ヶ月弱経ちまして少しは回復したのでまずはブログでリハビリ。
フォーラムに投稿された質問
メールアドレスを他の人と被らないよう、バリデーションを「users,mail_address」としました。
[解決済み] バリデーションで「unique」を指定した際のソフトデリートとの連携について - laravel.jp
usersテーブル自体はソフトデリートを有効にしています。 この場合、削除したユーザのメールアドレスと、新しく登録するユーザのメールアドレスが同じ場合、 バリデーションに引っ掛かって登録することができません。
どうにかソフトデリートとユニークなメールアドレスを両立させる方法はないでしょうか。
Laravel の Validator からはモデルがソフトデリート(論理削除を簡単に実装できる機能)を使ってるかどうかわからないので unique
ルールを適用したら削除したモデルがひっかかって辛いという話です。
再現するとこんな感じです。
<?php // マイグレーションファイル(抜粋) <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; class CreateUsersTable extends Migration { public function up() { Schema::create('users', function(Blueprint $table) { $table->increments('id'); $table->string('email'); $table->softDeletes(); $table->timestamps(); }); } } // シードファイル(抜粋) class UserTableSeeder extends Seeder { public function run() { // Model の $unguarded を true にすると楽 // これ豆知識な User::unguard(); User::create([ 'email' => 'test@example.com' ]); } } Route::get('unique', function() { User::destory(1); // 削除した! $email = 'test@example.com'; $v = Validator::make(['email' => $email], ['email' => 'unique:users']); // 削除したけどバリデーションはエラー! var_dump($v->fails()); });
ソフトデリートの場合、削除されるとカラムの deleted_at
に日付を入れるだけなので unique
で発行される SQL ではダメなわけです。ちなみにこんなSQLが発行されます。
select count(*) as aggregate from "users" where "email" = ?
上記 SQL の結果が 0 の場合 unique
バリデーションは通過します。
解決方法
クエリーへWHERE節として追加される条件を追加することも可能です。
<?php 'email' => 'unique:users,email_address,NULL,id,account_id,1'v4.2:バリデーション
なのでこんな感じで書いて上げればOK.
<?php Validator::make(['email' => $email], ['email' => 'unique:users,email,NULL,id,deleted_at,NULL']);
こうするとこんなSQLが発行されます。
select count(*) as aggregate from "users" where "email" = ? and "deleted_at" is null
where 節が付加されているのがわかりますね。
*1:なんか抜け毛が増えた気がする