HogeFugaHogera

IT系の備忘録とか、他徒然なるままに

laravelでHello, world!

やりたいこと

nginx下で、とりあえず「Hello, world!」を出力してみる。 ただ、英語だと当たり前すぎるので、ここはドイツ語で「Hallo, Welt!」としてみる。
その他のHello, world!が良い方は、こちらからどうぞ⇒Hello world - アンサイクロペディア

composerによるlaravelのインストール

  1. laravelをインストールしたいディレクトリに移動します。
  2. $ curl -sS https://getcomposer.org/installer | phpを実行します。
  3. $ ./composer.phar create-project laravel/laravel --prefer-distを実行します。

これでインストールは完了です。

初期設定

  1. `install_dir/laravel/app/config/app.phpを開きます。
  2. root urlを設定します。
    line 29: 'url' => 'http://xxxx'
  3. time zoneを設定します
    line 42: 'timezone' => '‘Asia/Tokyo'
  4. localeを設定します。
    `line 42: 'locale' => 'ja'
    ただ、この設定値はローカリゼーションで読み込まれる言語ファイルの指定らしいので、 現時点では行わなくても問題ないです。

パーミッションの設定

app/storagenに、Webサーバからのアクセスを許可します。
Nginxの実行ユーザがhogehogeなら、ディレクトリ以下の所有権をhogehogeに変更します。
# chown -R hogehoge app/storage

Nginxの設定

ブラウザからpublic/index.phpにアクセス出来るようにします。 ベースはSilexのNginx設定(http://silex.sensiolabs.org/doc/web_servers.html#nginx)からです。

ディレクトリとロケーションの構成は下図になります。

f:id:einstee:20131031170433p:plain

これに、アクセス時はindex.phpとなくても、アクセスできるようにします。
というよりも、*.phpというリクエストを404 Not Foundとします。

こんな面倒なディレクトリ構成イヤだよ!
という方はこちらのサイト様をご参考にください ⇒

Laravel4のインストールと初期設定|Laravel|PHP|スタッフブログ|京都のホームページ制作 株式会社Nextat(ネクスタット)

  1. Nginxの設定ファイルを開き、こんな感じにします(ex. /etc/nginx/nginx.conf)。
server {
    server_name  hoge.com;
    listen 80;

    location = /hoge {
        try_files @app @app;
    }

    location ~ ^/hoge/(.*/)?.*\.php$ {
        return 404;
    }

    location ~ ^/hoge(/.*)$ {
        root /www/laravel/public;
        try_files $1 @app;
    }

    location @app {
        root /www/laravel/public;
        fastcgi_pass unix:/usr/local/php/var/run/php-fpm.sock;
        fastcgi_param  SCRIPT_FILENAME  /www/laravel/public/index.php;
        include        fastcgi_params;
    }
}

2. サーバを再起動します。
nginx -s reload

Nginx設定の説明
  • サーバのドメイン名とポートを設定します。
server_name  hoge.com;
listen 80;
  • リクエストがhttp://hoge.com/hogeなら、下記ロケーションが実行されます。 =は完全一致なので、マッチしたら、このロケーションのみ実行されます。
location = /hoge {
    try_files @app @app;
}
  • リクエストがhttp://hoge.com/hoge/XXX/.../XXX.phpなら、下記ロケーションが実行されれます。
    マッチ法は~(正規表現)です。このロケーションにマッチすると、404 Not Foundがレスポンスされます。
location ~ ^/hoge/(.*/)?.*\.php$ {
   return 404;
}
  • リクエストがhttp://hoge.com/hoge/xxx...なら、下記のロケーションが実行されます。 マッチ法は~(正規表現)で、上と同じです。正規表現マッチのロケーションが複数ある場合は、
    上から順に、マッチしたものが実行されます。 なので、上の条件と逆にすると、*.phpというリクエストは実行されてしまいます。
location ~ ^/hoge(/.*)$ {
    root /www/laravel/public;
    try_files $1 @app;
}
  • @appで指定された内部リダイレクト先になります。 SCRIPT_FILENAMEは強制的に/www/laravel/public/index.phpとします。
location @app {
    root /www/laravel/public;
    fastcgi_pass unix:/usr/local/php/var/run/php-fpm.sock;
    fastcgi_param  SCRIPT_FILENAME  /www/laravel/public/index.php;
    include        fastcgi_params;
}

try_files って何さ?

公式サイトの日本語訳を以下にのせます。
非公式な私訳ですので、間違いがあれば教えてください。

構文:   try_files file ... uri;   
        try_files file ... =code;   
context:    server, location   

指定されたファイルが存在するか確認し、リクエスト処理に最初に見つかったファイルを使用する。 
その処理は、現在のコンテキスト上で行われる。   
指定されたファイルへのパスは、ルートとエイリアスディレクティブに従ったファイルパラメータから構成される。   
終端が"/"で指定されたディレクトリの存在をチェックできる(例:“$uri/”)。   
もしファイルが見つからなければ、最後に設定されたuriが内部リダイレクトとして使用される。

ルーティングの設定

たぶん、こんなロケーションにしなければ、すでに既存のスタートページがご覧頂ける筈です。
今のままだと、こんなエラーページしか見れません。

f:id:einstee:20131101170749p:plain

見たい目かっこいいのでこのままでもいい気もしますが、目的は「Hallo, Welt!」の表示なので、なぜこんなことになるのか考えます。

リクエストがルーティングに一致しない

表示されたエラーページを見ると、throwされている例外がNotFoundHttpExceptionです。
リクエスト先がlalavel上に見つからないみたいです。
なので、一体どんなリクエストが出ているのか調べてみます。

ブラウザからhttp://hoge.com/hogeにアクセスするとき
期待されるリクエストは/ですが、実際にlarvelが受け取ったリクエスト(エラーページのREQUEST_URI)は/hoge
すなわち、サブパス(という良い方でいいのか?)の/hogeにpublicディレクトリを対応させたから 直感的にはlaravelにも、http://hoge.com/hogeより下の部分が渡されると考えてしまいます。 しかし、実際にlaravelに渡されるリクエストは
laravelに渡されるリクエスト = ブラウザからリクエストされたURL - server_name
となっている訳です。
だから、nginxかlaravel上で帳尻を合わせる必要があります。

laravelで帳尻を合わせる

app/routes.phpを編集します。

Route::get('/hoge', function()
{
        return "Hallo, Welt!";
});

これで、http://hoge.com/hogeにアクセスすると、「Hallo, Welt!」と表示されます。

終わりに

もしかしたら、Nginxで帳尻を合わせる方法や、Laravel上でもっと良い解決法があるのかもしれません。
もしご存知の方や、アイディアがある方は、教えて頂けると幸いです。

参考サイト様

Laravel4 日本語ドキュメント
nginx連載5回目: nginxの設定、その3 - locationディレクティブ - インフラエンジニアway - Powered by HEARTBEATS