Ansible と Vagrant で HHVM をためそう
作ったよ
入れてるもの
Laravel が入ってるのは仕様です。上記は全部 task として分けてあるので必要ないものとかは外しちゃってください。
学んだこと
- apt-get update するときに
cache_valid_time
つけておくと毎回走らなくていい感じ - HHVM のインストールはかなり楽になった
- Laravel のインストールで Composer 使ってるんだけど HHVM はすぐタイムアウトするので
ResourceLimit.SocketDefaultTimeout
を設定しなければならない- server.ini を編集すればよいのだろうか? 不明。
不具合
Laravel をインストールした後に chmod -R 777 laravel/app/storage
してるんだけど、起動時に生成される laravel.log やセッションが permission denied になる。どうすればいいんだっけ?
最後に
変なとこあったら、このエントリにコメントいただけるか @localdisk まだリプライください。Pull Request でもOK.
Laravel 勉強会福岡に行ってきました
有給とって遠方の勉強会に参加する喜び、プライスレス。
というわけでLaravel勉強会福岡 〜Fukuoka.php企画〜 - Fukuoka.php | Doorkeeperに参加してきました。大阪から @shin1x1 さんと @msng さんが来られてて非常に有意義な勉強会になりました。ネットを介してコミュニケーションを取るのと、実際に会って色々話すのとでは得られるもの(というか性質)が違うなーと改めて思った次第。
Laravel 勉強会福岡では大阪から来たお二人と僕で色々とお話させていただきました。内容は
僕が作ったサンプルアプリはTuts+に公開されている twitter クローンである Ribbitを Laravel 4.1 で実装したものです。ソースはgithubにありますのでよしなにしてください。何かのお役にたてば幸い。
勉強会での個人的なハイライトとしては「スライド作らずにやろうかな」と言っていたにも関わらず、発表時にはきっちりスライドを仕上げてきた @shin1x1 さんと @msng さんでしょうか。ソースコードをプロジェクタに映して説明した僕だけ、すごい浮いてました。マラソン大会で「一緒に走ろうな」と言われて、ゴール直前で置いて行かれたあの気分を久しぶりに味わいました。ちくしょう。
最後にお知らせですが、4/26 にFuelPHP&CodeIgniter ユーザの集い #4 : ATNDに参加します。CodeIgniterをモダン方面に改造した話をしたいと思います。
Laravel の Model Event
[FuelPHPのORMでinsert前とかをフックして何か処理をする (´・ω・`) - 杏z 学習帳
を見て、Laravel の Model Event
を思い出したので書いておきます。
上記みたいに Model
をあれやこれやする前後に処理をはさみたい! ということがあると思います。Laravel には Model Event
という仕組みが用意されていて楽に書くことができます。
書き方
インサートする前にログを出力したい場合です。
<?php class Sample extends Eloquent { // boot をオーバーライド protected static function boot() { parent::boot(); // インサート前なので creating メソッドを定義 self::creating(function($ribbit) { Log::info('保存するよ'); }); } }
Model Event
は、Event
クラスの仕組みが使われており、Model
周りはかなり細かくイベントが定義されています。
定義されている Mode Event
- creating
- インサート前
- created
- インサート後
- updating
- アップデート前
- updated
- アップデート後
- saving
- インサート前及びアップデート前
- saved
- インサート後及びアップデート後
- deleting
- デリート前
- deleted
- デリート後
- restoring
- ソフトデリート復帰前
- restored
- ソフトデリート復帰後
Model Observer
FuelPHP のように Model Observer
を作成することもできます。
まず、Observer
を用意して…。
<?php class SampleObserver { public function creating($model) { if (条件) { // return false するとインサートは行われません return false; } } }
Observer
を定義します。
<?php Sample::observe(new SampleObserver);
で OK です。
Laravel 勉強会福岡 が 4/4 に開催されます
NetBeans Connector が荒ぶる場合の対処方法
NetBeans8 がリリースされて早一週間。便利に使ってますか? 僕は使ってます。
さて、NetBeans には NetBeans Connector という Chrome 拡張があってこれを導入するとプロジェクト単位で LiveReload できるという便利機能があります。
でまぁ日々便利に使っているわけですが、どうもブラウザの更新が頻繁に走るので ??? となることがあります。このたび原因と対処法がわかったのでブログに書きます。
原因
ログが出力されたりキャッシュができるたびに LiveReload が走ってた。あぁ…ってなりました。あぁ…そういうことね…。
対処法
プロジェクトのプロパティの "無視されたフォルダ" にログ出力されるフォルダを指定する。
オチ
ちゃんと書いてるじゃないか。俺のバカ!バカ!!
Laravel の Event クラスを使って処理をまとめてみる
Laravel の Event
クラスは、任意の Event
を発行できます。今回はメール送信処理をまとめてみましょう。
- 参考
- イベント
まずは Event::fire
でイベントを発行します。
<?php public function postRegister() { // ユーザ登録 ……… // メール送信 Event::fire('emails.user.register', ['件名', 'fromメールアドレス', 'toメールアドレス', ['データ']]); }
この例では、ユーザー登録後、emails.user.register
というイベントを発行しています。
そしてイベントの受け取りは以下のようになります。
<?php // app/start/global.php Event::listen('emails.*', function($subject, $from, $to, $data) { Mail::pretend(); // デバッグ用 Mail::send(Event::firing(), $data, function($message) use ($from, $to, $subject) { $message->from($from)->to($to)->subject($subject); }); });
Event::listen
の第一引数の emails.*
はワイルドカードリスナーといって emails.
以降のどんな文字列のイベントが発行されても受け取ることができます。
そして、Mail::send
の第一引数である Event::firing
は発行されたイベントの文字列が取得できます(この場合は emails.user.register)。
今回は、イベント発行の文字列とメールテンプレート(app/views/emails/user/register.blade.php)の場所を一致させることによってメール送信処理をこのようにまとめてみました。
こちらからは以上です。
Laravelでプライマリキーを使った1:1関連のテーブル分割で自動採番をしないようにする
- プライマリキーを使った1:1関連でカラム数の多いテーブルを分割する - Hidden in Plain Sight
- プライマリキーを使った1:1関連のテーブル分割で自動採番をしないようにする - かみぽわーる
を Laravel でも同じようにできるよな。と思って書いてみたらちょっとハマったので Laravel 使っている人は気をつけましょうという話。
問題はカラム毎に charset の指定ができないので、カラム長を 255 にして utf8mb4 を default charset にするといわゆる 767bytes 問題が発生する。
解決方法としては
DB::statement
を使用してALTER TABLE
してカラムの charset を指定する。- カラム長を短くする。
- utf8mb4 をやめる。
2 と 3 は 根本的な解決にはなりませんよね?*1 というわけで 1 の方法で解決をはかりましょう。
マイグレートファイル
users
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function(Blueprint $table) { $table->increments('id'); $table->string('email')->unique(); $table->string('password'); $table->timestamps(); $table->index('email'); }); DB::statement('ALTER TABLE users MODIFY email varchar(255) CHARACTER SET ascii COLLATE ascii_bin'); DB::statement('ALTER TABLE users MODIFY password varchar(255) CHARACTER SET ascii COLLATE ascii_bin'); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } }
profiles
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; class CreateProfilesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('profiles', function(Blueprint $table) { $table->integer('id')->unsigned(); $table->string('name')->nullable(); $table->tinyInteger('gender')->nullable(); $table->dateTime('birthday')->nullable(); $table->timestamps(); $table->primary('id'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('profiles'); } }
で OK です。
最後に
migrate の SQL を確認したいときは pretend
オプションをつけると確認できます。
上記 2 テーブルのマイグレート SQL はこんな感じです。
$php artisan migrate --pretend CreateUsersTable: create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null, `password` varchar(255) not null, `created_at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8mb4 CreateUsersTable: alter table `users` add index users_email_index(`email`) CreateUsersTable: alter table `users` add unique users_email_unique(`email`) CreateUsersTable: ALTER TABLE users MODIFY email varchar(255) CHARACTER SET ascii COLLATE ascii_bin CreateUsersTable: ALTER TABLE users MODIFY password varchar(255) CHARACTER SET ascii COLLATE ascii_bin CreateProfilesTable: create table `profiles` (`id` int unsigned not null, `name` varchar(255) null, `gender` tinyint null, `birthday` datetime null, `created_at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8mb4 CreateProfilesTable: alter table `profiles` add primary key profiles_id_primary(`id`)
(追記)モデルの実装
モデルではこんな感じ。hasOne
及び belongsTo
の第2引数がポイントです。
<?php class User extends Eloquent { public function profile() { return $this->hasOne('Profile', 'id'); } } class Profile extends Eloquent { public function user() { return $this->belongsTo('User', 'id'); } } $profile = User::find(1)->profile;
*1:ぜひ、リンクを踏んでイラッとしていただきたい
ルートパラメータをフィルターから取得する
小ネタ。フィルターからルートパラメータを取得する方法。
<?php // filters.php Route::filter('param', function() { // Route は \Illuminate\Routing\Router のエイリアス // なので Route::current で \Illuminate\Routing\Route // クラスを取得して parameter メソッドを呼べば取れる dd(Route::current()->parameter('name')); }); // routes.php Route::get('/user/{name}', ['before' => 'param', function($name) { return; }]); // http://localhost/user/hoge // -> hoge
個人ユースに WordPress は必要ない
上記を乱暴にまとめちゃうと「WordPress を個人のブログで使うのはオーバースペックじゃね?」という話でそれはそのとおり。
WordPressって使うのは簡単だけど、使いこなすのは難しい。テーマやプラグインは膨大で自分が必要なものを探すにはある程度の情報収集力を必要とするし、導入したものが安全とは限らない。
自由に広告をはりたいとか、SEO で優位に立ちたいという理由で WordPress を選ぶのは悪手でしかない。livedoor Blog や はてなブログ の有料版を使えばいいんじゃないかと思います。
お金を掛けたくないんなら、それこそHTMLを書いてFTPでアップロードする古式ゆかしい方法を使う手もある。日替わりタイトルのようにそっけないデザインでスマホにも対応していないのに、かなりのアクセスを誇るサイトもある。*1
面倒だけど難しいことはなにもないのでおすすめ。
最初は頑張れる!という人なら静的サイトジェネレータを検討してみるのもありだ。
それでも WordPress を使いたい人は転んでも泣かないように。
最後にどうでもよい話だけど、WordPress は mysql 関数の使用から mysqli 関数への移行を進めてるみたい。なんで PDO じゃないん?
WordPress/wp-includes/wp-db.php at master · WordPress/WordPress · GitHub
NetBeans をうまく使って Grunt とおさらばする
Grunt は確かに便利なんだけど「それ NetBeans でできるよ」という話。
LiveReload
NetBeans Connector 使えばOK.
- Chrome Web Store - NetBeans Connector を Chrome にインストール
- プロジェクトのプロパティ -> ブラウザ で "NetBeans Connector 組込みの Chrome" を選択する
- あとは NetBeans からプロジェクトを実行するだけ
これで LiveReload を使う必要がなくなります。
SCSS/LESS のコンパイル
NetBeans は標準で対応してます。
参考: NetBeans で Sass を使う - localdisk
CSS/Javascript の minify
JS CSS Minify Compress Plugin を使う。あるいは Assetic をデプロイ時に叩くような仕組みを作る。Rocketeer のタスクに組み込めばかなり自由にあれこれできるので面白いです。
まとめ
流行の開発環境に目移りするのも分かりますし悪いことでもないとは思うのですが、今自分が使っている開発環境を見なおして磨いてみるのも一つの選択肢として頭に入れておくとより捗るのではないかと思います。