Laravel4でArtisanによるCLI開発
Laravel4の便利機能のひとつにArtisanというコマンドラインツールが存在します。
プロジェクトルートにて、php artisan ***** とコマンドを打つことで、様々な命令を実行させることができる機能です。
今回は、とりあえず、CSVデータを読み込んで、DBにデータを保存するサンプルを作っていくことにします。
[下準備と前提条件]
[コマンドクラスの作成]
- プロジェクトルートにて以下のコマンドを実行
- php artisan command:make ItemImport
- app/command/ディレクトリにItemImportクラスファイルが生成される。
- オートロードのクラスマップに反映させるために、composer dump-autoloadもしておきましょう。
- php artisan command:make ItemImport
[処理を記述]
- ItemImportクラスファイルを開いて、以下を修正
- protected $name : artisanコマンドで呼び出す際のコマンド名
- protected $description : listやhelpを実行した時に表示されるコマンドの説明文
- getArguments():コマンドが受け取る引数(今回は使いません)
- 初期状態では、array('example', InputArgument::REQUIRED, 'An example argument.')となっているので、コメントアウト。
- getOptions():コマンドが受け取るオプション(今回は使いません)
-肝心の処理はfireメソッドに記述する。
<?php class ItemImport extends Command { protected $name = 'new-item'; protected $description = 'New Item Impoert!'; /* 中略 */ public function fire(){ // CSV $handle = fopen(storage_path()."/db/item.csv", "r"); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE){ // Eloquentでデータを挿入 $item=new Item; $item->item_code=$data[0]; $item->item_name=$data[1]; $item->item_price=$data[2]; $item->save(); } echo "Completed!"; } protected function getArguments(){ return array( //array('example', InputArgument::REQUIRED, 'An example argument.'), ); }
さぁ、これで使える!と思いきや、実はまだやることがあります。作ったコマンドをアプリケーションに登録しなければなりません。
方法は簡単で、app/start/artisan.phpを開いて、以下のように追加してあげればいいだけです。
<?php Artisan::add(new ItemImport);
これで、準備OK。プロジェクトルートにて、以下のコマンドを実行
- php artisan item-import
- Completed!と表示されていれば、成功です。おめでとうございます。
ORM Eloquentに追加された新機能
Laravel4の正式リリースまであと1ヶ月ちょっとらしい。現在はBeta5の開発段階。
フレームワークとしての仕様もほぼ固まってきて、おそらく、大幅な変更点は無いだろうということでEloquentの新しい機能を紹介します。
- コレクション
<?php // 全ての商品一覧を取得 $itemList=Item::all(); // 最初の商品名と最後の商品名を表示 echo $item->first()->item_name; echo $item->last()->item_name; // もちろん普通にforeachで回せる foreach($itemList as $value){ echo $value->item_name; } // 普通の配列のようにアクセスできたり echo $itemList[2]->item_name; // 要素数を取ってきたりも echo $itemList->count(); // コレクションの中に任意のIDが存在するかチェックできたりもする if($itemList->contains($key)){ echo "あるよ"; } // JSONに変換したり $json=$itemList->toJson(); // ただの配列に変換したり $array=$itemList->toArray();
- 時にはコレクションのデータを操作したい事もあるでしょう。そこで、eachとfilterのメソッド。
- 要素に対して、コールバック関数を適応できる。
- eachは単純なループ。全ての要素に対して平等に行われます。filterは該当しない要素を削除してくれます。
- filterは内部でarray_filterをしている事になるので、必ずbool値を返さなければならない。
- falseを返した場合は、コレクションから削除されます。また、bool値を返さなくても、同じ扱いです。
<?php // 全ての商品一覧を取得 $itemList=Item::all(); // 全ての商品名にビックリマークを付与 $itemList->each(function($item){ $item->item_name=$item->item_name."!"; }); // コレクションの中で1000円未満の商品を削除 $itemList->filter(function($item){ if($item->price < 1000){ return false; } return true; }); // 表示 foreach($itemList as $value){ echo $value->item_name.":"; echo $value->price."<br />"; }
と、このように、DBから取ってきた後の一手間として、eachとfilterが使えるようになりました。
個人的には、やや使い所は難しい気もしますが、Laravel3ではなかった機能なので、何らかの形で使ってみたい。
- クエリースコープ
- Ruby on RailsのモデルにあるScopeがLaravel4にも実装されました。
- scopeMethodName($query)という形式でメソッドを作成すれば、よく使う、条件式を予め登録できる機能。
- 以下のサンプルでは、商品テーブルに削除フラグ=del_flgと公開フラグ=public_flgのある商品テーブルがあると仮定する。
- 削除フラグは0デフォルトで1が削除扱い。公開フラグは0が未公開で1が公開の扱い。
- つまり、販売中の商品は削除フラグが0で、公開フラグが1という状態。
- でも、この条件を毎回書くのは面倒。そこでクエリースコープ。
- 以下のサンプルでは、商品テーブルに削除フラグ=del_flgと公開フラグ=public_flgのある商品テーブルがあると仮定する。
-
- モデルファイルの定義
<?php class Item extends Eloquent { protected $table = 'item'; protected $primaryKey = "item_id"; public $timestamps = false; public function scopePublicItem($query){ $query->where('del_flg', '=', 0); $query->where('public_flg', '=', 1); } }
-
- どうやって呼び出すか?
<?php // こう書いていたのが・・・ $itemList=Item::where("del_flg","=",0)->where("public_flg","=",1)->get(); // こんなにシンプルに!呼び出しはscopoを取り除いて、camelCase形式で呼び出す。 $itemList=Item::publicItem()->get(); // 更に条件を追加してもOK $itemList=Item::publicItem()->where("price",">",500)->get(); // こっちでも同じ $itemList=Item::where("price",">",500)->publicItem()->get();
- この、スコープにはwhere句だけでなく、Laravelのクエリービルダーで使えるメソッドが使える。
- よって、whereBetweenもOKだし、orderByでソートも可能。よく使うクエリー条件はスコープメソッドで定義しておくと、グンと効率が上がります。
という事で、今日はこのくらいで...
公式のマニュアルが現在、大幅に追記されていますので、そちらも参照して下さい。
Laravel4で廃止されたdd()関数みたいなものを組み込む
Laravel3系で結構、重宝していた関数であるデータダンプ用の関数=dd関数。
しかし、残念ながら、Laravel4では廃止になったようです。
「Laravel4ではComposerという便利機能があるので、欲しい人は、自分で探してインストール下さい。」
おそらく、そういう方針なんでしょう。もちろん、要望が高まれば、いずれ、取り込まれる可能性もあるかもしれませんが。
ただ、今のところ、そんな気配はないっぽいです。
で、data-dump関数で良い物があるのか、Composerでインスールできるパッケージを探してみました。
https://packagist.org/
キーワード検索で dump と入力してみると...いろいろ出てきます。
で、今回、注目してみたのが、dump_r()です。
https://packagist.org/packages/leeoniya/dump-r
↓実行結果はこんな感じで、とっても、見やすい!
http://o-0.me/dump_r/
インストール方法はとても、簡単で、プロジェクトルートのcomposer.jsonのrequireのセクションに
"leeoniya/dump-r": "dev-master" を追記するだけ。json形式なので前後の , に気をつけて。
そして、Composer updateを実行。これで、dd関数の代用ができました。
<?php dump_r($obj);
他にも、Composerでインストールできるいろんなパッケージがあるので、探してみると結構面白いです。
Laravel4でコントローラーの作成とモデルの作成に関する簡単なまとめ
Laravel4のBeta4がリリースされ動きが活発なLaravel。
Laravel4のコントローラーの作成とモデルの作成に関する簡単なまとめを残しておこうと思います。
[下準備]
- Laravel4のインストールについては前のエントリーを参照して下さい。
[新しいコントローラーの作成]
- app/controllers/のディレクトリに新しいコントローラーの作成する
- デフォルトではBaseControllerとHomeControllerのふたつ。
- サンプルとして、このディレクトリにShopControllerという名前のコントローラーを作成する
- ファイル名は一応、ShopController.php。ただし、必ずしも、この名前じゃなければいけないわけではない。詳しくは後述。
- BaseControllerを継承するコントローラークラス
- アクションとして、indexアクションを作成する。
<?php class ShopController extends BaseController { public function getIndex(){ return "Shop Index!"; } }
ただし、この状態で、http://localhost/project/public/shop/にアクセスしてもエラーになるだけ。
- ここからが重要。
- Laravel4では新しいクラスファイルを作成した場合、プロジェクトルートにて、composer dump-autoloadを実行しなければならない。
- このコマンドを実行することによって、ShopControllerの存在がプロジェクトに認識されることになる。
- Generating autoload filesと表示されればOK。
- このコマンドを実行することによって、ShopControllerの存在がプロジェクトに認識されることになる。
- 正しく、ShopControllerの存在が認識されているか確認するには?
- Laravel4では新しいクラスファイルを作成した場合、プロジェクトルートにて、composer dump-autoloadを実行しなければならない。
<?php // autoload_classmap.php generated by Composer $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'BaseController' => $baseDir . '/app/controllers/BaseController.php', 'DatabaseSeeder' => $baseDir . '/app/database/seeds/DatabaseSeeder.php', 'HomeController' => $baseDir . '/app/controllers/HomeController.php', /** 中略 **/ 'ShopController' => $baseDir . '/app/controllers/ShopController.php', 'TestCase' => $baseDir . '/app/tests/TestCase.php', 'User' => $baseDir . '/app/models/User.php', );
コントローラークラスのオートロードが確認できたら、今度はルーティングの設定。
作ったコントローラーを呼び出すための定義をしなければならない。
- app/routes.phpを開く
- デフォルトでは、publicルートの定義のみが行われているだけ。
- project/public/shop/というURIで呼び出すためのコントローラーを登録するためには?
- Route::controller('shop', 'ShopController');
- 基本これだけでOK。
- Route::controller('shop', 'ShopController');
で、ブラウザでhttp://localhost/project/public/shop/にアクセス!
Shop Index!と表示されていれば、ひとまず、コントローラーの作成に成功!
[新しいモデルの作成]
- モデルファイルを作って、DBからデータを取得するサンプルにチャレンジしてみる。
- DBはとりあえず、MySQLで、商品テーブルからデータを取得するという想定で。
- 商品情報が保存されているitemテーブルには、商品ID=item_id=主キー、商品名=item_name、価格=item_priceの3つのフィールドがあるする。
- サンプルデータは適当に入れておいて下さい。
- DBはとりあえず、MySQLで、商品テーブルからデータを取得するという想定で。
- まずは、app/config/database.phpにある、mysqlの項目を環境に合わせて変更。
<?php 'mysql' => array( 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'sample_db', 'username' => 'user', 'password' => 'password', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ),
- 次にモデルクラスの作成。app/models/にItem.phpというファイルを作成。
- ItemクラスはLaravelのORMである、Eloquentクラスを継承する。コードは以下の様な具合で。
<?php class Item extends Eloquent { protected $table = 'item'; protected $primaryKey = "item_id"; public $timestamps = false; }
- $timestampsは created_atとupdated_atのフィールドを更新するためのもの。今回のテーブルには両方共存在しないので、falseを設定。
- 次はコントローラークラスを作成した時と同様に、プロジェクトルートにて、composer dump-autoloadを実行。Generating autoload filesと表示されていればOK。
[コントローラーにアクションメソッドを追加]
<?php class ShopController extends BaseController { public function getList(){ foreach(Item::all() as $item){ echo $item->item_name."<br />"; } } }
-
-
- http://localhost/project/public/shop/list/へアクセスして、商品名一覧が表示されていれば、無事、成功。
-
とりあえず、今日はここまで。追記もあるかもしれません。
Laravel4で「HelloWorld」を表示させるまで
最近、ようやく、注目が集まってきたPHPのWebアプリケーションフレームワークLaravelのLaravel4 Beta4が
リリースされたので、HelloWorldを出力するまでの流れを簡単に書いていこうと思います。
【Laravel4のインストール】
- Laravel4はLaravel3とは違ったインスール方法が採用されている。
- ComposerというPHPのパッケージ管理システムを使ったインスールになる。
- Composerとは何か?
- 公式サイト http://getcomposer.org/
- まず、Composerをインストールしなければならない。
- ComposerのインストールとPATHの設定を確認した後
{ "require": { "laravel/framework": "4.0.*" }, "autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php" ] }, "minimum-stability": "dev" }
- requireの項目に、"laravel/framework": "4.0.*" という記述が。
- どういうことか?
- https://packagist.org/packages/からrequireで指定されたパッケージのバージョンがダウロード&インストールされる。
- https://packagist.org/packages/laravel/framework/へブラウザでアクセスすると、Laravelのパッケージ一覧が閲覧できる。
- requireの項目に "laravel/framework": "4.0.*@dev"を指定すると最新版が、"laravel/framework": "v4.0.0-BETA3"を指定すると、BETA3がインストールされる。
- requireでバージョンが指定されていない場合minimum-stabilityの値が"dev"となっているので、最新版が自動的にインストールされる形になる。
- どういうことか?
- どうやってインストールする?
<?php // autoload_classmap.php generated by Composer $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'BaseController' => $baseDir . '/app/controllers/BaseController.php', 'DatabaseSeeder' => $baseDir . '/app/database/seeds/DatabaseSeeder.php', 'HomeController' => $baseDir . '/app/controllers/HomeController.php', /* 中略 */ 'User' => $baseDir . '/app/models/User.php', );
<?php // autoload_namespaces.php generated by Composer $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'Symfony\\Component\\Translation\\' => $vendorDir . '/symfony/translation/', 'Symfony\\Component\\Routing\\' => $vendorDir . '/symfony/routing/', 'Symfony\\Component\\Process\\' => $vendorDir . '/symfony/process/', /* 中略 */ 'Illuminate' => $vendorDir . '/laravel/framework/src/', );
- で、ようやく、Laravel4の初期設定。
- php artisan key:generate を実行しておく。すると、app/config/app.php のkeyに値がセットされる。
- .htaccessを編集。
- RewriteBase /project_root/public/ 任意のディレクトリを指定
- 127.0.0.1/project_root/public/へアクセスする
- 「Hello World!」が出力されていればとりあえずは成功。
- app/routes.php にルーティングが定義されていおり、デフォルトではトップページのルーティングが定義されているだけ。詳しくは、別のエントリーで。
- ちなみに、このViewファイルはapp/views/hello.php。
- 127.0.0.1/project_root/public/へアクセスする
- RewriteBase /project_root/public/ 任意のディレクトリを指定
とりあえずは、今回は、こんな具合で終わり。
次は、新しいコントローラーの作成とルーティングの定義やモデルファイルの作成を書いていこうと思います。
- Laravel4のドキュメント
- http://four.laravel.com/docs/eloquent
- Hirohisa Kawaseさんによる 日本語ドキュメント https://leanpub.com/laravel4plus
LaravelのORM Eloquentで括弧を使ったクエリーのグループ化する方法
- 商品テーブルから削除フラグが0で公開ステータスが1の商品で、更に入力されたキーワードに該当する商品を取得したい
<?php // キーワード $keyword=Input::get("keyword"); // 検索 $itemList=Item::where("del_flg", "=", 0) ->where("item_public_status", "=", 1) ->where(function($query) use($keyword) { $query->where("item_name", "LIKE", "%$keyword%"); $query->or_where("item_meta_keywords", "LIKE", "%$keyword%"); $query->or_where("item_meta_description", "LIKE", "%$keyword%"); }) ->get();
- ポイントは無名関数を使うときに、useを使うこと。
- 無名関数内では、$keywordにアクセスできないためuse構文を使用する。
- useには複数指定できるので、引き継ぎたい変数をどんどんぶっこめばいいだけ。
- こうして実行されるSQL
SELECT * FROM `item` WHERE `del_flg` = '0' AND `item_public_status` = '1' AND (`item_name` LIKE '%チョコ%' OR `item_long_description` LIKE '%チョコ%' OR `item_meta_keywords` LIKE '%チョコ%' OR `item_meta_description` LIKE '%チョコ%')
LaravelのキャッシュでRedisを使う
PHPフレームワークのLaravelでキャッシュエンジンをRedisにしてみた。以外と、すんなり言ったので、記事を残しておく。
- Redisの概要
- Redisのインストール
- Laravelでの設定。
- application/config/database.php にRedisに関する項目を探す
<?php // application/config/database.php /* 中略 */ 'redis' => array( 'default' => array( 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0 ), ),
-
- キャッシュの設定
- ドライバーにRedisを指定する
- application/config/cache.php にRedisに関する項目を探す
- キャッシュの設定
<?php // application/config/cache.php 'driver' => 'redis'
基本これだけでOK。あとは通常通り、キャッシュを使えばいいだけ
<?php // 保存 // 3番目の引数は分数 Cache::put('key', 'value', 10); // 取得 $value= Cache::get('key'); // 削除 Cache::forget('key');