nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

ワンポイントTwelve-Factor App(3) : 設定

この記事は、The Twelve-Factor Appを補足し、実際に現代的なWebアプリケーションで適用する場合の注意点などを紹介するシリーズです。下記の原文を読んだ上でのワンポイント解説になります。

12factor.net

概要

  • 設定は環境変数のみで分岐する
  • 設定はコードに含めない

これは何を表しているか

「1. コードベース」では、「ステージング」や「本番」といった環境によってコードを分けたりしてはいけないとありましたが、コードの中に入っている設定は別です。

設定とは、例えばデータベースの接続先、APIのキーといったものから、稼働環境のURLや、環境によって違う全ての値が対象となります。

フレームワークによっては、それ自体に環境毎に設定ファイルを作る機能が用意されている場合がありますが、それらを使ってしまうと環境毎に設定ファイルが必要になってしまい、環境を作るたびにコミットが生まれます。また、修正にもコミットして修正が必要になってしまいます。このような環境の違いがコードそのものに含まれていると、違う環境で動かすことが困難になってしまいますので、環境要因によるものはコードに含めてはいけません。

コードに含めないとなるとどこか別の場所に保存しないといけませんが、環境変数を使用することで多くの環境で共通で設定を差し込むことができます。特にsystemdやDockerでは環境変数の注入が簡単になっておりますので、積極的に利用することができます。

実際に運用する場合

設定をコードに含めないことによって、設定だけを書き換えて好きな環境でアプリケーションを起動することができるようになります。パスワードなどの機密情報をGitHub等にpushしてしまうと、そこから機密情報が漏れるといったリスクもありますので、設定が切り出されているのはセキュリティ的な点からも好ましい構成になります。

Dockerを使っている場合は前述の通り簡単に環境変数を扱うことができますが、開発環境でDockerを使わない場合はdotenvのようなツールを使って.envファイルを読めるようにするか、direnvのようなツールで注入する必要があります。

どう環境変数化するかについては、例えば「本番環境では動くけどステージングでは動かない」みたいなものを用意したい場合は、「なぜ動かしたくないのか」という理由を考え、そこの切り分けは「本番かステージングか」ではなく「それを動かす理由」の環境変数で切り替えるのが良いでしょう。

また、nginxやphp-fpmといった既成のサーバーアプリケーションの場合、起動前に環境変数を読むのが難しいですが、これらも環境変数で設定を切り分けるべきです。これらの場合は envsubst コマンドや、類似のテンプレートエンジンで設定ファイルを事前にレンダリングしてから起動するという手法で解決することができます。

フロントエンドの場合、「ビルド時に必要な設定」と「実行時に必要な設定」が存在します。ビルドはCIなどで自動で行い、実行はWebサーバー上で行われますので、それぞれ必要なタイミングが変わります。特にフロントエンドは構造上ビルド後に環境変数を読むことは困難ですが、12Factor Appではビルド結果を環境毎に分けてはいけませんので、起動時に一手間かける必要があります。

ワンポイントTwelve-Factor App(2) : 依存関係

この記事は、The Twelve-Factor Appを補足し、実際に現代的なWebアプリケーションで適用する場合の注意点などを紹介するシリーズです。下記の原文を読んだ上でのワンポイント解説になります。

12factor.net

概要

  • 依存関係を依存関係解決ツールを使って解決する
  • 暗黙に依存関係が存在することは許容しない

これは何を表しているか

いわゆるbundlerやcomposerといった依存関係解決ツールを使えという話です。これにより「それらは外部のものである」というのが明確になります。

「1. コードベース」と同様、1つのアプリケーションは1つのコードベースであるべきです。ライブラリのようなものは別のコードベースになるので、それを解決するために依存関係解決ツールを使うべきです。

また、依存関係解決ツールを使う場合でも、いわゆるグローバルにインストールするようなことはせず、必ずアプリケーションのローカルにインストールされるようにし、事前にインストールする必要がないようにしておきましょう。

依存関係には、ネイティブのライブラリ(curlImageMagickなど)を要求する場合もありますが、これらもアプリケーションに同梱していない場合は、バージョンアップによって動かなくなってしまうということがあります。これらもアプリケーションに同梱しておくのが良いです。Railsでnokogiriに苦戦した方は多いと思います。

実際に運用する場合

bundlerやcomposerといった依存関係解決ツールに関しては普通に使っていれば問題ないと思います。現代において依存関係解決ツールが存在しない言語は希少だと思いますので、お使いの言語のものを適切に利用してください。ほとんどのメジャーなフレームワークを使えば、デフォルトでそれらが適用されると思います。

依存関係のインストールに必要なネイティブのライブラリに関しては、Dockerを使うことによってそれらも簡単に固定バージョンのものを用意することが可能です。開発初期はどの環境でも最新バージョンを入手するのが簡単なのですが、開発が数年になると当時のバージョンがOSのパッケージシステムで入らず動かなくなるといったことが多々存在します。

現実的にはDockerを常に使うとは限りませんし、特に開発中はシステムのライブラリをそのまま使うことが多いので、その場合は依存バージョンをREADMEなどに記載することによって暫定的に回避するなどの対策を取っておきましょう。

フロントエンドで、CDNで配布されているものを<link>タグや<script>タグでそのまま使うケースがありますが、どこで何が読まれているのかを把握することが困難になってしまいます。フロントエンドも必ずnpmやyarn等で管理し、本番環境では1つのファイルにpackしたものを使用するようにしましょう。

ワンポイントTwelve-Factor App(1) : コードベース

この記事は、The Twelve-Factor Appを補足し、実際に現代的なWebアプリケーションで適用する場合の注意点などを紹介するシリーズです。下記の原文を読んだ上でのワンポイント解説になります。

12factor.net

概要

  • 単一のアプリケーション(システム)は単一のコードベースのみで成立する。
  • 単一のコードベースは単一のバージョン管理システムで変更を追跡している。
  • 環境によってコードを切り替えるようなことをしてはいけない。
  • 同一のコードを共有する複数のアプリケーションがある場合、それは依存関係管理ツールで管理する。

これは何を表しているか

「このアプリケーションはこのコードベースのみである」と明示しておくことによって、システムが明快になります。

これに違反しているというのはどういうことでしょうか。まず、「1アプリケーションが複数のコードベースで構成されている」というケースはどうなるでしょうか。それらのコードベースがそれぞれアプリケーションとして動作するものであれば、それは分散システム、現代的に言うのであればマイクロサービスみたいなものになります。その場合、各アプリケーションそれぞれが12Factor Appに即しているのであれば問題ありません。そうでない場合、システムが絡み合っているような状態になり、どこまでがどのアプリケーションなのかを把握するのが困難になります。

「複数のアプリケーションが1つのコードベース」というのは、ライブラリのようなものの場合になります。このような場合は、「どこまでがライブラリでどこまでがアプリケーションなのか」を把握するのが困難になるので、依存関係解決ツールを使用して明確に分離すべきです。

また、1つのアプリケーションを「ステージング」「本番」といった感じで複数の環境に配置する場合でも、必ず同一のコードをそれぞれの環境に展開するようにすべきです。「ステージングバージョン」「本番バージョン」というようなコードを作るべきではありません。これは「3. 設定」や「10. 開発/本番一致」などで重要になってきます。

実際に運用する場合

ここは書いてある通りですが、1アプリケーション=1リポジトリとし、外部ライブラリは依存関係解決ツールを利用しましょう。

前述の通り、「ステージング」や「本番」みたいな環境ごとで微妙に違うコードベース(ブランチなど)を用意するのもNGです。これらは設定で分離されるべきです。「3. 設定」で解説します。単一のコードベースでそれぞれの環境にデプロイすることで、環境間の

例外のケースとしては、OpenAPIやgRPCといった複数のアプリケーションにまたがる定義ファイルがあると思います。ただしこれらはそもそもプログラムではないので、いいのでないかという気はします。そこから生成されたコードはアプリケーションと同一リポジトリに格納しましょう。

Nuxt.jsにおけるサーバーサイドレンダリングの挙動とライフサイクル

Nuxt.jsというかSSR関係を触る際にまず疑問になるのは「どこまでがサーバーサイドレンダリング (SSR) でどこからがクライアントサイドレンダリング (CSR) なの?」ということだと思います。

基本

簡単に言えば、ブラウザでURL直接指定で開けばSSR、それ以降はCSR、ということになります。

当たり前ですが、サーバーサイドレンダリングはサーバーでの実行なので、windowオブジェクトも存在しないし、そこから外部サーバー(APIサーバーなど)にアクセスする際はそこからのアクセスになります。そのままではブラウザのcookieも利用できません。

axios-moduleは何をしているのか

上記の通り、SSRになった場合とCSRになった場合は通信経路も変わるしcookieの取扱も変わります。

これらを真面目に対応すると結構大変なのですが、 axios-module を使うと大体のことを解決してくれます。

axios-moduleは大きく以下のようなことを行ってくれます。

  • SSRの場合とCSRの場合でエンドポイントを切り替える
  • クライアントサイドのHTTPヘッダ(cookieなど)をサーバーにそのまま透過的に送信する

他にもいろいろありますが、重要なのはこの2点で、これにより通信時のレンダリング場所がサーバーかクライアントかを意識せずにAPIアクセス処理を書くことができるようになります。Nuxtで開発する場合は必須と言っても過言ではないでしょう。

なお、複数のエンドポイントを指定したりはできないので、API通信先は1箇所に固定されることになります。複数のエンドポイントが発生しそうな場合はクライアント(Nuxt)だけで解決せず、BFF (Backends For Frontends) パターンを用いて処理するのが良いでしょう。

ライフサイクル

Nuxtを使うとコンポーネントにメソッドが増えたり、ミドルウェアプラグインのような仕組みが追加されます。これらがSSRの場合とCSRの場合でどのように呼ばれるかは使ってみないとわからないところです。

そこで、サンプルプロジェクト を用意し、調査してみました。

初回アクセス (SSR)

そこからの遷移 (CSR)

つまりどういうことか

Nuxtでアプリを作る際は、SSRでもCSRでも問題なく表示できるように作る必要があります。また、クローラーなどからのアクセスは常にSSRになるため、クローラーなどに拾ってほしい情報はSSRの段階で確定させる必要があります。

一方で、windowオブジェクトにアクセスするもの、例えばlocalStorageを使うようなものはクライアントサイドのみでしか実行することはできません。 mounted 以外で書く場合は process.server 変数などを使って分岐させる必要があります。

特に注意したいのが created で( beforeCreate も)、SSR時とCSR時の両方で呼ばれます。普通に書くと二重に処理してしまうことになるので、意識して書かないと意図しない挙動になる可能性があります。

まとめ

このあたりの挙動は分散して書かれてはいるものの、1ページにまとまっているものが見つからなかったため、今回用意してみました。

SSRは便利ではあるものの、どうしても層が1つ増えるために挙動が複雑になります。ちゃんと把握していれば怖くないので、どこで何が動いているのかを意識しながら書くようにしましょう。

WEB+DB PRESS Vol.95で特集記事を書きました

こちらではお久しぶりです。nazoです。

この度、現在所属しているUUUM株式会社のメンバーと、HTTPに関する特集記事をWEB+DB PRESS Vol.95に書きました。2016年10月22日発売です。

雑誌記事の執筆というのは人生初で、わずか8ページ程度かと思いきや執筆はハードでした。本一冊書くのとかどれだけ大変なんだよと思いましたが、いつかは挑戦したいものです。

私のパートはHTTPヘッダの詳細についてということで、このページ数で何を伝えるべきか考えたのですが、この特集に興味がある人がどのようなこと知ることができると嬉しいのかを考えて厳選したつもりです。

他の記事も興味深いものばかりですので、書店で見かけたらよろしくお願いします。

APCキャッシュを安全に扱うSafeApcを作った

https://github.com/nazo/safeapc

なにこれ?

APC(APCu)のユーザーキャッシュ(アプリから指定するキャッシュ。ソースコードのキャッシュではない)を「そこそこ安全に」扱うための簡単なラッパーです。

どう使うの?

packagistに登録してあるので普通にcomposerから入れてください。

基本的には普通にapc_fetchとかするのがSafeApc::get等に変わっただけです。

あと、リクエストの最初に、以下を入れる必要があります。

// キャッシュで使用するリクエスト開始時間を指定
SafeApc::setCacheStartTime($_SERVER['REQUEST_TIME']);

// キャッシュのバージョン番号を指定(この例では外部ファイルから)
SafeApc::setCacheVersionKey(file_get_contents('apc_version'));

これだと何がいいの?

これにより、APCキャッシュの問題2つが改善されます。

ttlの時間は常にtime()を参照する問題

APCttlを指定した場合、そのttlの判定は、常に「APC関数を呼び出した時点でのtime()の戻り値」となります。

通常、Webアプリでは、処理中の内部時間がずれてしまうと内部時間の一貫性がなくなるため、リクエスト開始時刻をそのリクエスト中の時間とし、リクエスト中の処理が1秒以上経過しても、全ての更新時刻などはリクエスト開始時刻で扱うことが多いですが、APCttlはそこは当然無視されるので、ttlを厳密に扱おうとした場合に、微妙にずれる、ということが発生します。

例えば、以下のような感じです。

// このキャッシュは1秒だけ持たせよう
apc_store('key', 'value', 1);

// 適当な処理
sleep(3);

// 同一リクエスト中だしさっきのキャッシュ残ってるよね?→ない!
apc_fetch('key');

これを回避するために、ttlは86400で固定し、PHP側で生存時間を判定するようにしています。なんで86400固定なのかは後述。

全キャッシュクリアは高負荷だよ問題

APCの全キャッシュクリアは、同プロセスのAPC処理を全てブロックします。このため、確実に他の処理に悪影響が発生します。

また、PHP5.3以前&apache2 mod_phpでは、このブロックされている途中にmax_execution_time超え等で強制終了されると、ロックを開放せずに全プロセスを巻き込んで死ぬという挙動があります。(このへんの話

どちらにしても、全キャッシュクリアは危険なので、キャッシュクリアは2つの方法を組み合わせて行っています。というか、行ってください。

  • 無期限設定でも、必ず86400秒(1日)経過で自動で消える。(変更できます)
    • この時、86400秒で一斉に消えると高負荷になるので、ランダムで+0〜30秒増やしています。これによりキャッシュクリアのタイミングが、よりバラつくようになります。
    • デフォルトが86400秒なのには特に意味はありませんが、なんとなく1日くらい残ってくれれば大丈夫かなーという感じで指定しています。
  • キャッシュのバージョンを変えることによって、そもそも前のキャッシュキーにアクセスしないようにしている。
    • 内部的にはキャッシュのキーは「バージョン#本来のキー」という文字列になります。そのため、バージョンを変えると、古いキーには絶対にアクセスしません。
    • これはこれで、古いキーが1日残り続ける、という問題はあります。
    • 従って、「SafeApc::setCacheVersionKeyに与える引数を変える=キャッシュクリア」となります。
    • ついでに言うと、通常APCのキャッシュクリアは、Webサーバーのプロセス上で行わないといけないので、コマンドラインからの実行には一手間必要でしたが、この方法だとただバージョン番号を変えるだけなので、簡単にキャッシュクリアをコマンドライン上で行うことができます。

必要な設定

  • apc.user_ttlは何でもいいので必ず設定してください。0だと、メモリが溢れた場合に、apc_storettlを無視して全キャッシュクリアを行うという問題があります。
  • 削除を行わない方針のため、比較的メモリ使用量が増えやすいです。apc.shm_sizeは、「キャッシュの最大量 * 想定される1日のキャッシュクリア回数」くらいのサイズを指定しておきましょう。
  • 内部的にはapc_fetch等を呼んでいるので、APCuで使う場合はAPC互換モードでビルドしてください。(Enable full APC compatibility [yes] : yes)

まとめ

ここまで書いておいてアレですが、APCキャッシュは外部との通信がない分高速ですが、基本的にmemcachedかredisでいいと思います。APCだと複数サーバあるとその台数分キャッシュ生成処理が走るし。状況次第ですね。

某所で散々検証した内容なので、理論的には問題ないはずですが、このコード自体は全く使っていないしろくにテストしていないので、バグがあれば教えてください。

Laravel5を業務で一通り使ってみた感想

2ヶ月くらい使ってみたけど、悪くはないんだけど、なんか最近持ち上げられすぎてる気がするので、気になったところを書き出してみる。

あくまで個人的な感想なので、マサカリ投げるのは歓迎。

概要

Noticeを含むエラーが全て例外になる

最近のフレームワークは大体やってそうだけど、エラーを出すと全て例外を出すので、不要にcatchしなければ問答無用で落ちる。これにより、NOTICE出しっぱなしで何となく動いているコードを殲滅できる。標準にしてほしい。Fatalも例外として扱ってくれるが、Fatalを取れるのはプログラム終了後なので、特に意味はない。出力が同一フォーマットになるくらい。

ちなみに自前で実装するにはErrorExceptionのページに書いてあるので、この通り実装しよう。簡単である。

ファイルの配置が自由

composer autoload使っていればどれでもそうなんだけど、ModelとかServiceとか別に規定のフォルダに配置する必要はない。namespaceさえ解決できればどこからでも読み込める。これにより、アプリを複数に分けたいけどModelは共有したい、というような配置も簡単にできる。自分は本体と管理画面を別アプリにしつつ、Modelと、ビジネスロジック(いわゆるDDDにおけるサービス)は同一のディレクトリから参照している。

具体的には、composer.jsonに以下のように書き足せば良い。

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Model\\": "../models/"
        },

psr-4と書いてある通り、ここに記載したものは、PSR-4に準拠した形式でautoloadされる。簡単に言えば、jsonに記載したパスを起点として、namespaceの区切りとディレクトリ構造が一致している前提で読み込みに行く。今時autoload周りは自分で書くことはない。

Laravelはディレクトリの規定がほとんど無く、namespaceからautoloadできれば何をどこに置いても大体動くので、うまく使おう。

なぜかソースフォーマットがPSR-2無視

タブインデントしたり改行位置が独特だったり謎が多い。自動生成した時とかにイラッと来る。何で無視しているのかよくわからないが、とりあえずしばらくはこのままらしい

そもそもSymfony Component使いまくり

これのせいで、たまにソースを追うと、コアを読んでるはずなのに突然vendor/symfony以下に移動しないといけなくなってだるい(Requestとか)。それって結局Symfony系でいいのでは…?一方で、何でもフルスクラッチすればいいってものではないというのもわかる。

DIが強い

ControllerにDIし放題(後述のリフレクション)とか、FacadeとかContractの仕組みによってDIが簡単になっている。と思う。ナチュラルに使うのであまり意識することはない。ナチュラルに使えるくらい良く出来ているのではないかと思う。押し付け感は少ない。

ルーティング

prefixやドメイン名でグルーピングできたり、ルーティングでMiddlewareを足したりできるのでかなり優秀。LaravelCollectiveを使えばannotationで指定もできる。自分は使っていない。

Middlewareというのはいわゆるフィルタ的な、共通の事前処理のようなもの。認証チェックとかビューの共通変数を当てたりするのに使うことが多い。

リフレクション

例えば、Controllerのコンストラクタに、勝手に引数を追加したりすると、そのインスタンスが何故か勝手に渡ってくる。以下はドキュメントから引用

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;

class UserController extends Controller {

    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

}

この例では、コントローラーのコンストラクタに突然UserRepositoryが登場するが、実行するとちゃんとインスタンスが渡ってくる。例えばCakePHPだと、プロパティにprotected $uses = ['User'];のように、規定されたものを規定された通りに読み込むことしかできないが、このパターンであれば何でも注入することができる。

まあこれだけだと、普通にnewすればいいじゃん、とも思うが、Contractsと組み合わせると、Controllerに渡すのは定義だけで、実装を何にするかは別の場所で定義することができる。強い。

難点としては、リフレクション使いまくりなので、多分処理速度がかなり犠牲になっているのでは、と思う。ベンチマークはしていない。

Eloquent(O/Rマッパー)

Laravel標準のO/RマッパーであるEloquentだが、何故か今時ActiveRecordっぽい感じだったり、複合PKが扱えなかったり(ちょっと改造すると扱えるようになるが)と、時代遅れ感が強い。CakePHPですら3.0になってテーブルとエンティティを分離している

クエリビルダ自体はそこそこ優秀で、行ロックやバルクインサート、JOIN周りもちゃんと書けるので、実用的ではあるのだが、今時ならDataMapperを採用していただきたかったところ。フォローしておくと、Eloquent自体も、HasMany的なものは明示指定しない限り呼び出されない(余計なことをしない&自動Memoizeしてくれる)とか、Collectionが楽とか、いいところもある。

自分はあまり考えずに導入してしまい後戻りができなくなっているが、新規に書くのであれば、O/RマッパーだけDoctrineを使うことも十分に検討したほうがいいと思う。ただし認証周りなどのDBに依存する標準機能が全滅するので、そこはちょっと面倒。まあ認証あまり使ってないけど。

MigrationやSeeding(いわゆるfixture的なやつ)もあるけど、特にモデルと連動していないし、phpmigとかでいいんじゃないかなとも思う。Eloquent含めて全部セットで使うには便利だし、特に避ける理由はない。

認証

標準で認証周りが用意されているが、正直めんどくさい。

拡張性も十分に用意されているのだが、ドキュメントが少なく、結局ソースを読んでいるうちに最初からスクラッチで書けば済むのでは…という感じになる。ソースコード自体を再配布するようなものでなければ、標準のものは無視してスクラッチで書いてしまえばいいと思う。いずれにせよ、認証周りのソースコードAuthManagerGuardRegistrarあたり)は読んでおく必要がある。

Middleware+DIが優秀なので、自分で書くにもそんなに苦労はしないと思う。

Blade(テンプレートエンジン)

悪くないんだけど微妙。Twigに対するアドバンテージが特に思いつかない。せめてプラグイン的なものは用意してほしかったような…。テンプレート継承とかは用意されているし、PHP解釈できるから最小限のもの以外はPHPで書けばいいじゃんってのはわかるんだけど…。うーん…。

あとフォームヘルパはLaravelCollectiveに置いてある。そのままだとさすがにdefaultとかの処理が面倒なので使おう。

テンプレートの機能ではないが、old('name')と書くと、前回のフォーム入力情報を取得できるのは便利。入力失敗した時とかにわざわざController側で同じ入力値をViewに渡す必要がない。<input type="text" name="name" value="{{ old('name', $user->name) }}" />のように書くことが多い。(oldの第二引数はデフォルト値)

Storage

S3と通常のファイルシステムを同じように扱うことができる。これにより本番はS3、開発環境はファイルシステムということが簡単に書ける。便利。特定のファイルシステムの時だけの処理とかも書けるし、特に不満はない。

Laravel Elixir

gulpのラッパーだが、特にgulpのラッパーというもの以上の何かはない。素のgulpに比べて書きやすくはなっているが、複雑なことをしようとすると途端に面倒になるし、独自知識を覚えてもあまりメリットがないので、Laravelと心中するつもりでなければ、素直に素のgulpなり一般的なものを利用したほうがいい。JavaScriptなのでそもそもLaravelである必要も疑問。

同様の謎ラッパーにEnvoy(Ansible的なやつ)等もあるが、やはりAnsible使えよって思う。ってかLaravelCollectiveにも似たようなものがあるんですがそれは…。強いて言えば、Laravel Elixirと違い、こちらはPHPなので、なんでもPHPで書きたい!という人にはいいと思う。

キュー&タスクランナー

Envoyのほうじゃなくて、アプリ内タスクを動かすタスクランナー、つまりcron的なものが用意されている。いやcronで呼び出してはいるんだけどPHPはマルチスレッド系は絶望的なので、cronでスケジューリングしたりタスクキューを作ったりすることが多いが、これがPHP側で管理する方法が標準搭載されているのは良いと思う。と言ったものの、まだ使っていないので何とも言えない。実行プロセス数の制限とかどうするんだろう。

Homestead

Laravelがいきなり動くVagrant一式だが、何故かコマンドがPHPで書かれてて謎の努力を感じる。VagrantやHHVMの使用例として参考にする程度にはいいが、結局環境によって細かい変更するだろうし、自分で構築したほうがいいとは思う。ハンズオンとかで使うには便利だと思う。「Homestead入れておいてね」で済む。

テスト

まあ普通に書ける。URLにアクセスしてレスポンスを調べるようなテストも何も考えずに書ける。Migration+SeedingでDBが絡むテストも簡単に書ける。特に問題ない。

Dotenv

Laravelあまり関係ないけど、Laravelでは.envというファイルに設定を書く。これはphpdotenvの機能で、名前の通り、環境変数に相当するものを書くだけなので、環境変数として設定できるのであれば、どこからでも設定できる。例えばAWSのアクセスキーを最初から環境変数に入れている場合、改めて設定を書く必要がない。まあAWSの設定はaws-sdkが勝手に拾ってくれるけど…。

また、dotenvのような設定形式は他言語でもあるため(例えばgolangとか)、設定の共有が簡単に行うことができる。例えば、PHPでは苦手となる生socketを扱ってリアルタイム通信するような別プログラムと、メインのPHPアプリで、同じ設定ファイルを読む、といったことが可能になる。

Carbon

またLaravel関係ないが、Carbonに標準対応しているので、DBの日付設定とかが楽。

まとめ

個人的にはSilexでいいんじゃないかと思うことが多いが、まあこれはこれでいいんじゃないかなーと思う。よく検討してから使おう。でも好きなものがあるなら好きなものを使うのが一番だと思う。

Laravel関係ない内容が多いな…。