2016年2月14日日曜日

Laravel, LumenのSELECT文いろいろ

Laravel, LumenでSELECT文に慣れていないのでメモ。

参考

https://laravel.com/docs/5.1/eloquent#retrieving-single-models

SELECTもいろいろある

find

  • プライマリーキーでマッチした1レコードを取得する
  • 戻り値はモデルのインスタンス(stdClass)
  • 0件の場合は、null
$flight = Flight::find(1);

first

  • 条件にマッチした最初の1レコードを取得する
  • 戻り値はモデルのインスタンス(stdClass)
  • 0件の場合は、null
$flight = Flight::where('active', 1)->first();

get

  • 条件にマッチした全てのレコードを取得する
  • 戻り値は、配列(各レコードはstdClassオブジェクトのインスタンス)
  • 0件の場合は、オブジェクトが返る
$flight = Flight::where('active', 1)->get();

all

  • 全てのレコードを取得する
  • 戻り値は、配列(各レコードはstdClassオブジェクトのインスタンス)
  • 0件の場合は、オブジェクトが返る
$flight = Flight::all();

0件の場合の評価の違い

$flight = Flight::find(1);
if (!$flight ) {
  // 通る
}

$flight = Flight::where('id', 1)->first();
if (!$flight ) {
  // 通る
}

$flight = Flight::where('id', 1)->get();
if (!$flight) {
    // 通らない (オブジェクトが戻り値のため)
}
if (!count($flight)) {
    // 通る Countableインターフェース
}

$flight = Flight::where('id', 1)->get()->toArray();
if (!$flight) {
    // 通る (オブジェクトを配列に変換したため)
}
if (!count($flight)) {
    // 通る
}

$flight = Flight::all();
if (!$flight) {
    // 通らない (オブジェクトが戻り値のため)
}
if (!count($flight)) {
    // 通る Countableインターフェース
}

まとめ

  • get(), all()の場合は、0件の場合もオブジェクトが返る。
  • Objectはtrueということと、1件または複数レコード(get()を使うか)を意識して書けばよさそう。
  • Illuminate\Database\Eloquent\Collectionは、継承しているクラスがCountableインターフェースを実装していてcount()でitemsの件数が取れる。
Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
        (
        )
)


2016年2月4日木曜日

Lumenのタイムゾーン設定

Lumenを検証していたところ、時間がUTCになっていたのでメモ

Lumen5.1で時間を表示させたところUTCとなっていました。
echo date('Y-m-d H:i:s e P'); // 2016-02-04 09:00:23 UTC +00:00
Asia/Tokyoとなってほしいのですが、
アプリ側では何も設定していないので、lumenのソースを確認したところ見つかりました。

lumen-framework/src/Application.php

    public function __construct($basePath = null)
    {
        date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
        $this->basePath = $basePath;
        $this->bootstrapContainer();
        $this->registerErrorHandling();
    }
この場合、環境変数APP_TIMEZONEは設定していないのでUTCになるわけですが、
デフォルト値をphp.iniの設定にしてほしいのは私だけでしょうか。

Dotenvを使っている場合は、.envに追加
使っていない場合は、bootstrap/app.phpに設定を追加することにしました。

.env

APP_TIMEZONE=Asia/Tokyo

bootstrap/app.php

// Dotenv::load(__DIR__.'/../');
putenv('APP_TIMEZONE=Asia/Tokyo');
軽量フレームワークなので、かゆいところは自分で対応する必要があるわけですが、
これはドキュメントに書いてほしいですね。