Laravel : http requestからルーティングまでのkernel処理の流れ

ユーザがアクセスしてきた時に、requestからresponseまでの処理がどうなっているのか?
1. /public/.httaccess が読み込まれる
2. RewriteCond %{REQUEST_FILENAME}により、該当ディレクトリ、該当ファイルが読み込まれる
3. /public/index.php が呼ばれる
4. index.phpにより、カーネル処理が登録される
5. ルーティング処理

### 1,2 /public/.httaccess
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
-> RewriteCondで、該当ディレクトリ、該当ファイルが読み込まれる
-> RewriteCond に記述した条件が満たされた時のみ RewriteRule に記述したURLの書き換えと転送が実行される

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

### 3~4./public/index.php
– autoload.php、bootstrap/app.phpが読み込まれる
 (controllerのuse classを使用する為)
– アプリケーションインスタンスの生成
 (Illuminate\Foundation\Applicationのインスタンス)
– カーネル処理
 (app/Http/Kernel.phpに渡される。その際に「環境設定」「エラーハンドラー」「ミドルウェア」「サービスプロバイダ」などが読み込まれる)
 HTTPカーネルがサービスプロバイダを登録する際に、web.phpファイルが読み込まれる
– リクエストのディスパッチ

require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);

### 5. Illuminate\Contracts\Http\Kernel

public function bootstrap();
public function handle($request);
public function terminate($request, $response);
public function getApplication();

### 6. ルーティング
– ファサードを使い、Illuminate\Routing\Routerクラスの各メソッドを使う

vendor/laravel/framework/src/illuminateに機能が揃ってますね。

Laravelでnpm&Gulpの使い方

まずnode.js & npm が入っているか確認
$ node -v
v8.16.2
$ npm -v
6.4.1

※入っていなければ、repoを追加
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
$ yum install -y gcc-c++ make
$ sudo yum install -y nodejs

gulpが入っているか確認
$ gulp -v
CLI version: 2.2.0
Local version: Unknown

※入っていなければ、npmインストール
$ npm i --global gulp

### npm install
プロジェクトのディレクトリでnpm install
$ npm install

dependencyでエラーになるときは、package.jsonを削除して、npm install。その後、必要なモジュールを入れます。

$ npm install gulp-sass –save-dev
$ npm install node-sass@latest
$ npm install laravel-elixir –save-dev

gulpが使えるようになります。
$ gulp

### assetの配置
resourceにjs,sassなどを配置し、gulp, webpackでpublicにコンパイルする
./resources/assets/js
./resources/assets/css
※よくCSSを./public/css/style.cssで編集するチュートリアルを見るが、実際に開発する際には、resources内で開発する

### gulp file編集

var elixir = require('laravel-elixir');

elixir(function(mix) {
    mix.sass('app.scss')
    .styles([
    	'libs/blog-post.css',
    	'libs/bootstrap.css',
    	'libs/bootstrap.min.css',
    	'libs/font-awesome.css',
    	'libs/metisMenu.css',
    	'libs/sb-admin-2.css',
    	'libs/styles.css'
    ], './public/css/libs.css')

    .scripts([
    	'libs/bootstrap.js',
    	'libs/bootstrap.min.js',
    	'libs/jquery.js',
    	'libs/metisMenu.js',
    	'libs/sb-admin-2.js',
    	'libs/scripts.js'
    ], './public/js/libs.js')
});

### gulp実行
$ gulp

フロントエンドとサーバーサイドを分けて開発するのであれば、sassへのコンパイルはフロント側でやればいいのかもしれないが、フルスタックエンジニアで開発する場合や、保守開発でのフロント編集の場合は、そのまま/resources/assetsで編集して、./publicにコンパイルすれば良いという事です。
こう考えると、フロントエンジニアでもLaravelの仕組みが分かっているとかなりコミュニケーションが楽になりそうですし、フロントエンド・サーバーサイドのスキル・興味関心に応じてどういう体制にするか考えるポイントになりそうです。

blade property {{ __(‘Login’) }}

/rosources/views/layouts/app.blade.php

<li class="nav-item">
                                <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                            </li>

この{{ __(‘Login’) }}を変えると。

/rosources/lang/en/login.php

return [
    'Login' => 'ログイン2',
];

/rosources/views/layouts/app.blade.php

<li class="nav-item">
                                <a class="nav-link" href="{{ route('login') }}">{{ __('login.Login') }}</a>
                                <!-- <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a> -->
                            </li>

なるほど、{{ __(‘${hoge}’) }}は、ローカルのヘルパーのようですね。
参考:https://laravel.com/docs/5.6/localization#retrieving-translation-strings

サクッといきます。このあたりは、面倒ですな。

{{ config(‘app.name’, ‘Laravel’) }}って何?

/resources/views/layout/app.blade.php

{{ config('app.name', 'Laravel') }}

これは、config/app.php の env’APP_NAME’を読み込んでいるという意味。

    'name' => env('APP_NAME', 'Laravel'),

env’APP_NAME’は.envのAPP_NAMEを読み込んでおり、なければLaravelって表示する、という意味だ。

APP_NAME=Laravel
APP_ENV=local

したがって、.envのAPP_NAMEを”フリーランスプラットフォーム”と変更すると

APP_NAME=フリーランスプラットフォーム
APP_ENV=local
APP_KEY=hoge
APP_DEBUG=true
APP_URL=http://localhost

このように変わる。

Upload image with Laravel5.7

Upload images with Laravel5.7.
Configure routing to save images posted from view.

Route::get('/image/index', 'ImageIndexController@index');
Route::post('/image/index', 'ImageIndexController@store');

imageindex.blade.php

@extends('layouts.image')
@section('title', '画像管理')

@section('breadcrumb')
	@@parent
	<ul class="breadcrumb">
      <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb" >
        <a href="/top" itemprop="url">
          <span itemprop="title">ホーム</span>
        </a>
      </li>
      <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb" >
        <a href="/top" itemprop="url">
          <span itemprop="title">画像管理</span>
        </a>
      </li>
    </ul>
@endsection

@section('content')
<h2>画像管理</h2>
      <hr>
      <form action="/image/index" method="POST" enctype="multipart/form-data">
        <div id="drag-drop-area">
         <div class="drag-drop-inside">
          <p class="drag-drop-info">ここにファイルをアップロード</p>
          <p>または</p>
          <!-- <input type="file" value="ファイルを選択" name="image"> -->
          <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="image"></p>
              <!-- <input type="submit" value="送信"> -->
           </div>
          </div>
            

      <div class="button_wrapper remodal-bg">
         <button type="submit" value="送信" id="square_btn" onClick="location.href='#modal'">登録</button>
      </div>
       </form> 

      <!-- remodal -->
      <div class="remodal" data-remodal-id="modal">
        <button data-remodal-action="close" class="remodal-close"></button>
        <h1>保存しますか</h1>
        <p>
          入力した内容で宜しいでしょうか?
        </p>
        <br>
        <button data-remodal-action="cancel" class="remodal-cancel">Cancel</button>
        <button data-remodal-action="confirm" class="remodal-confirm">OK</button>
      </div>
      <!-- /remodal -->

      <script>
      var fileArea = document.getElementById('drag-drop-area');
      var fileInput = document.getElementById('fileInput');

      fileArea.addEventListener('dragover', function(evt){
        evt.preventDefault();
        fileArea.classList.add('dragover');
      });

      fileArea.addEventListener('dragleave', function(evt){
        evt.preventDefault();
        fileArea.classList.remove('dragover');
      });

      fileArea.addEventListener('drop', function(evt){
        evt.preventDefault();
        fileArea.classList.remove('dragenter');
        var files = evt.dataTransfer.files;
        fileInput.files = files;
      });

      </script>
      
@endsection

laravel5.7 radioボタンのbladeでswitch文を使う

入力フォーム radioボタンで、値(value)にintを入れる。

<td>
            <input type="radio" name="role" size="40" value="1" v-model="message" checked> 管理者
            <input type="radio" name="role" size="40" value="2" <?php if( old('role')  == 2){ echo "checked";} ?> v-model="message"> 管理者2
            <input type="radio" name="role" size="40" value="3" <?php if( old('role')  == 3){ echo "checked";} ?> v-model="message"> 管理者3
            <input type="radio" name="role" size="40" value="4" <?php if( old('role')  == 4){ echo "checked";} ?> v-model="message"> 管理者4
            <input type="radio" name="role" size="40" value="5" <?php if( old('role')  == 5){ echo "checked";} ?> v-

確認画面でvalueを受ける際に、intを受けると、そのまま1~5の数字が表示されてしまう。

<tr>
          <th>権限</th>
          <td>
            {{$confirm->role}}
          </td>
        </tr>

oh my god

switch文でテキストに変換する。switch文は特にlaravelは関係ない。普通にphpで使えばよい。

<tr>
          <th>権限</th>
          <td>
            <?php
              switch ($confirm->role){
                  case '1':
                  echo "管理者1";
                  break;
                  case '2':
                  echo "管理者2";
                  break;
                  case '3':
                  echo "管理者3";
                  break;
                  case '4':
                  echo "管理者4";
                  break;
                  case '5':
                  echo "管理者5";
                  break;
              }
            ?>
            <!-- {{$confirm->role}} -->
          </td>

view

決まった

laravel5.7 ラジオボタン(radio)のinputform

view.blade.php
フォームで、radioボタンの値を渡したい。
最初、なにを土地狂ったのか以下のように書いていた。上手く値が渡らない。なぜなら、valueがnullだから。

<td>
            <input type="radio" name="role" size="40" value="{{ old('role') }}" v-model="message" checked> 管理者1
            <input type="radio" name="role" size="40" value="{{ old('role') }}" v-model="message"> 管理者2
            <input type="radio" name="role" size="40" value="{{ old('role') }}" v-model="message"> 管理者3
            <input type="radio" name="role" size="40" value="{{ old('role') }}" v-model="message"> 管理者4
            <input type="radio" name="role" size="40" value="{{ old('role') }}" v-model="message"> 管理者5
          </td>

ちゃうねん、radioボタンなので、valueは指定しないと駄目。
で、error時にはカスタムバリエーションから戻ってくるので、if文で、old(‘role’)が2の時は、checkedとすれば良い。

<td>
            <input type="radio" name="role" size="40" value="1" v-model="message" checked> 管理者
            <input type="radio" name="role" size="40" value="2" <?php if( old('role')  == 2){ echo "checked";} ?> v-model="message"> 管理者2
            <input type="radio" name="role" size="40" value="3" <?php if( old('role')  == 3){ echo "checked";} ?> v-model="message"> 管理者3
            <input type="radio" name="role" size="40" value="4" <?php if( old('role')  == 4){ echo "checked";} ?> v-model="message"> 管理者4
            <input type="radio" name="role" size="40" value="5" <?php if( old('role')  == 5){ echo "checked";} ?> v-model="message"> 管理者5
          </td>

決まった

あれ、ちょっとまてよ。確認画面で、radioボタンのvalueを以下の様に渡すと、

<tr>
          <th>権限</th>
          <td>
            {{$confirm->role}}
          </td>
        </tr>

おいおい、権限 “2” ってなんだよw

これはswitch文か?

Laravel5.7に静的HTMLファイルを配置する

Laravel5.7で静的HTMLファイルを配置する場合

/resources/views配下の*.blade.php はcontrollerで呼び出しているので、viewsディレクトリではなく、/public配下に*.htmlを配置する。

例: help.htmlを置いてみます。

help.html

hello

htmlを確認すると、反映されています。

Laravel5.7 テンプレートの継承

公式ドキュメントのBladeテンプレートの継承に習って構築していきます。
https://readouble.com/laravel/5.7/ja/blade.html

レイアウト定義
Bladeビューとして定義する。マスターのテンプレート名は迷いますね。公式ドキュメントではapp.blade.phpと記載がありますが、これは悩みますな。
とりあえず入れてみます。
/resources/views/app.blade.php

<!DOCTYPE html>
<html>
  <head>
  	<meta http-equiv="Content-Type" charset="utf-8">
    <title>@yield('title')</title>
    <meta name="description" content="Zeusはメール配信管理システムです。" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css" rel="stylesheet">
    <link rel="stylesheet" href="{{ asset('/css/style.css') }}">
    <link rel="stylesheet" href="{{ asset('/css/main.css') }}">
    <link rel="shortcut icon" href="/assets/img/favicon.png">
    <script src=""></script>
  </head>
  <body>
   <!-- 共通ヘッダー -->
   <div id="header">
    <h1><a href="/"><img src="/asset/img/log.png" alt="" />Zeus</a></h1>
    <ul id="helpNav">
        <li><a href="/top.html">ホーム</a></li>
        <li><a href="/logout.html">ログアウト</a></li>
    </ul>    
    <ul id="gNav">
        <li class="menu__single"><a href="/profile">アカウント一覧</a>
        <ul class="second_level">
          <li><a href="/profile">プロフィール詳細</a></li>
          <li><a href="/account/index">アカウント一覧</a></li>
          <li><a href="/account/input">アカウント新規登録</a></li>
          <li><a href="/company/index">原稿管理会社一覧</a></li>
        </ul>
        </li>
        <li class="menu__single"><a href="/manu/index">原稿一覧</a>
        <ul class="second_level">
          <li><a href="/manu/index">原稿一覧</a></li>
        </ul>
        </li>
        <li class="menu__single"><a href="/help.index">Zeusについて</a>
          <ul class="second_level">
            <li><a href="/help.index">ヘルプ</a></li>
            <li><a href="/manual/zeus.pdf">マニュアル</a></li>
            <li><a href="/rules.html">利用規約</a></li>
            <li><a href="/login">ログイン</a></li>
          </ul>
        </li>
        </ul>
    </div>
    <!-- / 共通ヘッダー -->

    <div id="content">
      @yield('content');
    </div>

    <!-- 共通フッター -->
  	<footer>
  		hpscript
  	</footer>
    <!-- / 共通フッター -->
  </body>
</html>

継承するレイアウトを指定する
resources/views/top.blade.php

@extends('app')
@section('title', 'トップページ')

@section('content')
<div id="top-main">
         <h2>Zeus</h2>
         <p>原稿作成・入稿ツールです。<br>原稿の作成・保存・入稿作業にご利用いただくことができます。</p>
      </div>
      <div id="news_h">
            <p>お知らせ</p>
      </div>
      <div id="news_t">
            <p>2018/10/17 ツールをリニューアルしました。</p>
      </div>
@endsection

ああああああああああ、これはマジで凄い。
Laravelびっくりした。

便宜的にlayoutフォルダの下に格納した方が良さそうですね。

Laravel5.7 bladeファイルをインクルードする手順

1. 何をインクルード化するか決める
2. /resources/views/ 配下にテンプレート化するbladeファイルを作成する
3. 2で作成した共通ファイルにインクルードする内容を書く
4. @include(”)構文を利用してインクルードする

1. 何をインクルード化するか決める
なにをインクルードするか。
パーツとして思いつくのは、head、header navi、footer。他にもあるかもしれないが、まずは、この3つをインクルードする。

2. /resources/views/ 配下にテンプレート化するbladeファイルを作成する
共通ヘッダをインクルードするため、common-head.blade.phpをviewsディレクトリ配下に作る。

3. 2で作成した共通ファイルにインクルードする内容を書く
あれ、titleはインクルードできないじゃん。

<head>
  	<meta http-equiv="Content-Type" charset="utf-8">
    <title>トップページ</title>
    <meta name="description" content="Zeusはメール配信管理システムです。" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css" rel="stylesheet">
    <link rel="stylesheet" href="asset/css/style.css">
    <link rel="stylesheet" href="asset/css/main.css">
    <link rel="shortcut icon" href="/assets/img/favicon.png">
    <script src=""></script>
  </head>

もう一度しっかり公式ドキュメントを見てみよう。
Bladeテンプレートについて記載がありました。
https://readouble.com/laravel/5.7/ja/blade.html
やり直しましょうw