ECサイト運営開発記

PHPフレームワーク Laravelの使い方を中心とした通販サイトの開発日記

初の日本語書籍「Laravel エキスパート養成読本」

4月21日 技術評論社から「Laravel エキスパート養成読本」が発売されるようで、著者の一人でもある川瀬裕久さんから
1冊献本していただきました。

内容に関しては、なんとな〜くLaravelを使っているユーザーにはうれしい内容で「IoCコンテナって何のためにある?」とか「ファサードはどういう原理で動いているの?」などの疑問に答えてくれる一冊。ただのMVCモデルのWebアプリケーションフレームワークを使うのはなく、仕組みを理解した上で、更に上手に使いこなしたいという人が読むべき本。

また、インストールからコマンドラインの解説などもあるので、入門書としても○。

Laravel3から5への歩み。新機能の解説や注意点なども最新版のLaravelを試したい人向けの情報もきっちり抑えてあるので、暫く机の横に置いておきたい1冊になると思う。

書店などで見かけた場合は、ぜひ、手に取ってみてほしい。

ADAちいさな水辺セット

売り切れ続出でずっと欠品だったADAの「ちいさな水辺セット」がペンギンビレッジ有楽町店に入荷、早速買ってきた。
佗び草*1、20cmのキューブ水槽、砂利がセットになって、4,500円(税抜)。激安というわけではないけれど、手軽にアクアリウムを始めることができるちょっとめずらしい商品。


箱の中には、水槽と佗び草ハンガーの2つと、スターターマニュアルなどの冊子が入っているだけ。
店頭で購入する場合、佗び草の棚から、エキノドルスが入った佗び草から好みの物を一つ選ぶ。


で、セットアップは非常に簡単で、砂利を洗い、佗び草ハンガーをかけそこに佗び草を置いて、塩素を中和した水を土台の半分が水に浸かるくらいまで注ぐだけ。10分もかからない。


運用方法も簡単で、液体肥料を混ぜた水を1日数回、水に使っていない葉っぱに、霧吹きをしてあげるだけ。
水草自体に水の浄化能力があるので、フィルターなどは不要。夏場はヒーターなしでいけるが、生体を入れている場合、冬は特に必要になる。
生体を入れる場合は、5匹程度が理想で、エビやタニシなども多すぎない程度に。
多すぎると水が汚れる原因になりますし、苔も発生しやすくなり、魚も死にます。

魚はベタ1匹とかメダカ3匹などがいいかもれない。

水替えは汚れ具合に応じて週に一度を目安に半分程度を交換。


注水した結果、少し濁ってしまった。日が経てば、透明になっていくはず。
出来るだけ、水草育成のため、日があたる場所に置いてあげるのが、望ましく、順調に育っていくと、土台から根が伸びて行ったり、水草も新しい芽を出してくるなどします。
とりあえず、1週間くらいは生体なしでやっていこう。

*1:土と肥料が混ざったボールのようなの土台に水草が植えられており、これを水槽内に入れるだけで、簡単に育成する便利な代物。

Kindleで読める 今のところ、面白いマンガ −ヒナまつり、予告犯、となりの関くん、僕だけがいない街

ヒナまつり
電子書籍版1巻〜4巻が発売中。未完の作品。
大武政夫のデビュー作。


芦川組の若手ヤクザ・新田義史が超能力少女・ヒナに振り回されるギャグ漫画。
ヒナが一体、どこの世界から来たのかは未だに不明だが、ヒナを中心とした人物模様がとにかく面白い。
ほぼ全員がボケで全員がツッコミ。

「予告犯」
電子書籍版1巻〜2巻発売中。未完の作品。
筒井哲也の作品。

インターネット動画を使い犯罪を予告&実行。主に殺人を行う。
女刑事の吉野絵里香が予告犯の「シンブンシ」を追う。作品は追う側の刑事と追われる側の予告犯の2つの視点
で描かれている。昨今のインターネット事情や社会の閉塞感がこの漫画にも反映されており、予告犯に共感する人も多そうな作品。

となりの関くん
電子書籍版1巻〜4巻発売中。未完の作品。
森繁拓真の作品。

中学生の関くんが、授業中になぜか先生に気づかれずに、机の上で一人壮大な遊びをし、隣の横井さんがそれをヒヤヒヤしながら見守る話。
関くんの遊びは、もはやなんでもありで、横井さんのイマジネーションあるツッコミと解説も手伝って、ただの遊びが壮大なドラマになる。
作中、関くんは一切喋らないので、実質、主人公は横井さん。アニメ化も決まっており、アニメで関くんが喋るかどうかも注目。

僕だけがいない街
1巻〜2巻発売中。未完の作品。
三部 けいの作品。

時間移動ものの作品。売れない漫画家・藤沼が、小学生時代に起きた連続・誘拐殺人事件の犯人と母親を殺した犯人を突き止める。
主人公は時間を巻き戻せる不思議な力を持ってはいるが、自由自在に扱えるわけではなく、むしろ、突如、時間が巻き戻る事の方が多い。
母親の死と過去に起きた連続・誘拐殺人事件がどう関係してくるのか?犯人は誰なのか?非常に気になる所。
無難に考えれば、小学校時代の先生が怪しいんだけど、同級生という可能性もありそう。とにかく、3巻に期待。

Laravel4でArtisanによるCLI開発

Laravel4の便利機能のひとつにArtisanというコマンドラインツールが存在します。
プロジェクトルートにて、php artisan ***** とコマンドを打つことで、様々な命令を実行させることができる機能です。
今回は、とりあえず、CSVデータを読み込んで、DBにデータを保存するサンプルを作っていくことにします。

[下準備と前提条件]

  • CSVファイルは以下の形式とする
  • ファイル名はitem.csv
    • ファイルは app/storage/csv/ に保存する
  • Eloquentクラスを継承したItemクラスはすでに作成済みとする。

[コマンドクラスの作成]

  • プロジェクトルートにて以下のコマンドを実行
    • php artisan command:make ItemImport
      • app/command/ディレクトリにItemImportクラスファイルが生成される。
      • オートロードのクラスマップに反映させるために、composer dump-autoloadもしておきましょう。

[処理を記述]

  • 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の新しい機能を紹介します。

  • コレクション
    • Laravel4のEloquentでは、DBからの取得結果をコレクションにして返却してくれるようになりました。
      • Eloquentのコレクションはイテレーターやら配列アクセスやらJSON変換やらいろんなインターフェースを実装してる。
<?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という状態。
        • でも、この条件を毎回書くのは面倒。そこでクエリースコープ。
    • モデルファイルの定義
<?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のコントローラーの作成とモデルの作成に関する簡単なまとめを残しておこうと思います。

[下準備]

[新しいコントローラーの作成]

  • app/controllers/のディレクトリに新しいコントローラーの作成する
    • デフォルトではBaseControllerとHomeControllerのふたつ。
  • サンプルとして、このディレクトリにShopControllerという名前のコントローラーを作成する
    • ファイル名は一応、ShopController.php。ただし、必ずしも、この名前じゃなければいけないわけではない。詳しくは後述。
    • BaseControllerを継承するコントローラークラス
    • アクションとして、indexアクションを作成する。
      • アクションメソッドはHTTPメソッド+アクション名の形。
        • アクション名がindexでGETで呼び出される場合は、getIndex。POSTで呼び出される場合は、postIndexという具合。
      • 以下のコードでは、ただ、Shop Index! という文字列がブラウザ上に表示されるサンプル。
        • return "String" で文字列が出力されます。
        • 同様にViewオブジェクトをreturnした場合も、文字列が返却されるので、ブラウザにHTMLが出力されます。
<?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の存在が認識されているか確認するには?
      • vendor/composer/autoload_classmap.phpを開いてみればわかる。
      • 長〜い配列の中に、自身で作成したShopControllerがオートロード一覧に入っていれば、OK。
      • 見てみれば、なんとなくわかるように、ファイルとクラス名のマッピングが行われており、ファイル名は実はshop.phpでもOKだったりする。
        • 例えば、ファイル名がyamada.phpでもコードの中でShopContorllerと書いてあれば、ShopControllerがマッピングされる。もちろん、望ましくはない。
<?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。

で、ブラウザでhttp://localhost/project/public/shop/にアクセス!
Shop Index!と表示されていれば、ひとまず、コントローラーの作成に成功!

[新しいモデルの作成]

  • モデルファイルを作って、DBからデータを取得するサンプルにチャレンジしてみる。
    • DBはとりあえず、MySQLで、商品テーブルからデータを取得するという想定で。
      • 商品情報が保存されているitemテーブルには、商品ID=item_id=主キー、商品名=item_name、価格=item_priceの3つのフィールドがあるする。
      • サンプルデータは適当に入れておいて下さい。
  • まずは、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。

[コントローラーにアクションメソッドを追加]

    • 先ほど、作成したShopControllerにgetListメソッドを追加。
      • メソッドはGETで呼び出され、全ての商品名を出力するコードを記述。
    • ORMのEloquentの詳しい使い方に関しては、ドキュメントを参照してみて下さい。
      • なんらかのフレームワークを使ったことがある人には、それほど、習得の敷居は高くないと思います。
<?php
class ShopController extends BaseController {

	public function getList(){
	  foreach(Item::all() as $item){
	    echo $item->item_name."<br />";
 	  }
	}

}

とりあえず、今日はここまで。追記もあるかもしれません。