【Laravel】第二回 自動販売機システムを作ろう! 〜マスタメンテナンス画面の作成〜

Laravel
マイケル
マイケル
どうもみなさんこんにちは!
マイケルです!
エレキベア
エレキベア
クマ〜〜〜〜!!
マイケル
マイケル
今回は前回に引き続き、
自動販売機システムを作っていきます!
エレキベア
エレキベア
前回はテーブル作成までだったクマね
マイケル
マイケル
うん!
ここから実際に画面をつくっていくぞ!
今回はメンテナンス画面の作成です!!
スポンサーリンク

参考書籍

マイケル
マイケル
基本的な実装方法などは、
前回に引き続きこちらを参考にして進めていきます。

エレキベア
エレキベア
やったるクマ〜〜〜〜!!

メンテナンス画面の仕様

マイケル
マイケル
復習になりますが、
メンテナンス画面の仕様は以下の通りです!
Screenshot 2020 11 12 23 25 16
↑自動販売機:メンテナンス画面
Screenshot 2020 11 12 22 20 01
Screenshot 2020 11 12 8 14 25
↑juiceテーブルの構成
マイケル
マイケル
juiceテーブルのマスタメンテナンス画面となっており、
前レコードの登録・検索・更新・削除の処理が行えるようになっています!
エレキベア
エレキベア
いわゆるCRUDシステムというわけクマね
CRUDとは
  • 主にデータベース管理システムについて用いられ、
    Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)の機能のことである!
マイケル
マイケル
その通り!
CRUDはWEBアプリの基本だね!
マイケル
マイケル
この画面を使うと、以下のように画面上でテーブル内容の編集ができます。
EDIT
エレキベア
エレキベア
これは楽しみクマね〜〜〜〜

メンテナンス画面の開発

マイケル
マイケル
今回作るのは下記の赤枠の範囲です!
MVCモデルの定義に沿って、Model、View、Controllerの各内容を紹介していきます!
Mindmap
エレキベア
エレキベア
やったるクマ〜〜〜!!
ところでMVCモデルって何クマ??
マイケル
マイケル
MVCモデルはWEBアプリケーションの考え方の一つで、

・Model → DBデータのやり取り
・View → 画面の表示
・Controller → Modelの操作やViewの表示等、処理を制御する

といった役割に分けて作成する考えなんだ!
エレキベア
エレキベア
なるほどクマね〜〜
LaravelはMVCモデルを採用してるのクマね
マイケル
マイケル
そういうことだ!
さっそく見ていこう!

Model

マイケル
マイケル
まずはDBデータのやり取りを行うために、
下記コマンドでjuiceテーブルのModelクラスを作ります!
php artisan make:model Juice
↑juiceテーブルのModelクラス作成
マイケル
マイケル
するとappフォルダ配下にファイルが作成されるため、
$table -> テーブル名
$primaryKey -> 主キー項目名

を記述します!
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Juice extends Model
{
    protected $table = 'juice';
    protected $primaryKey = 'id';
    protected $guarded = array('id');
}
↑テーブル名、主キーを設定
エレキベア
エレキベア
$guardedは何の設定クマ?
マイケル
マイケル
$guardedはModelクラスを使って更新を行うときに、
値を反映しない項目を定義するんだ!
マイケル
マイケル
今回の場合だとIDは自動インクリメントで設定されるから、
更新項目として設定する必要がないわけだからね。
エレキベア
エレキベア
そういうことクマね
Modelクラスは簡潔でわかりやすいクマ

View

マイケル
マイケル
Modelを作成したら次はViewの作成だ!
Laravelでは Bladeというテンプレートエンジンを使用して記述することができます!
マイケル
マイケル
app/resources/views配下に下記フォルダ・ファイルを作成しましょう!
■ juiceapp.blade.php
格納先:app/resources/views/layouts
<html>
<head>
    <title>***ENEGY SOUL***</title>
    <style>
        body { font-family:Arial; font-size:16pt; color:#555555; background-color:#f5f5f5; margin:5px;}
        hr { margin:5px 20px; border-top:1px dashed #555555; }
        .title-area { position:relative; background-color:#333333; height:100px; width:100%; }
        .title-area span { position:absolute; top:10px; left:15px; color:#eeeeee; font-size:45pt; text-align:left; letter-spacing:-4pt; }
        .message-area { position:relative; height:50px; width:100%; font-size:13pt; overflow-y: scroll; }
        .message-area .msg { position:absolute; left:15px; }
        .message-area .err_msg { position:absolute; left:15px; color:red; }
        .footer { text-align:left; font-size:10pt; margin:10px; border-top:solid 1px #ccc; color:#ccc; }
        .juice-table th { background-color:#999; color:#fff; padding:5px 10px; }
        .juice-table td { vertical-align:top; border: solid 1px #aaa; color:#999; padding:5px 5px; }
        .juice-table .ju_image { width:70px; }
        .juice-table .buttun-area { background-color:none; border:none; display:table-cell; vertical-align:middle; }
        .juice-table .ins_button { background-color:#333333; height:45px; width:80px; border-radius:7%; color:#eee; font-size:15px; cursor:pointer; }
        .juice-table .upd_button { background-color:#0066FF; height:45px; width:80px; border-radius:7%; color:#eee; font-size:15px; cursor:pointer; }
        .juice-table .del_button { background-color:#FF3333; height:45px; width:80px; border-radius:7%; color:#eee; font-size:15px; cursor:pointer; }
        .image-table td { border:none; }
        .juice-table-title { font-size:18px; margin:15px 0px 0px 0px; }
    </style>
</head>
<body>
    <div class="title-area">
        <span>@yield('title')</span>
    </div>
    <div class="message-area">
        @yield('message')
    </div>
    <hr size="1">
    <div class="content">
        @yield('content')
    </div>
    <div class="footer">
        @yield('footer')
    </div>
</body>
</html>
■ index.blade.php
格納先:app/resources/views/edit
@extends('layouts.juiceapp')

@section('title', 'ENEGY SOUL*')

@section('message')
    @if (count($errors) > 0)
        <span class="err_msg">
            @foreach ($errors->all() as $error)
                <div>・{{$error}}</div>
            @endforeach
        </span>
    @else
        <span class="msg">
            <div>・マスタメンテナンス画面でござる。</div>
        </span>
        @endif
@endsection

@section('content')
    <div class="juice-table-title">■新規追加</div>
    <table class="juice-table">
        <tr><th>自動販売機ID</th><th>ジュース名</th><th>価格</th><th>在庫</th><th>画像</th><td class="buttun-area"></td></tr>
        <form action="/edit" method="post" enctype="multipart/form-data">
            @csrf
            <tr>
                <td><input type="number" name="m_id" value="{{old('m_id')}}" min="1" max="100"></td>
                <td><input type="text" name="name" value="{{old('name')}}"></td>
                <td><input type="number" name="price" value="{{old('price')}}" min="1" max="1000">円</td>
                <td><input type="number" name="stock" value="{{old('stock')}}" min="0" max="100">個</td>
                <td><input id="image" type="file" name="image" value="{{old('image')}}"></td>
                <td class="buttun-area">
                    <input type="submit" class="ins_button" name="insert_juice" value="登録">
                </td>
            </tr>
        </form>
    </table>
    <hr size="1">
    <div class="juice-table-title">■テーブル情報</div>
    <table class="juice-table">
        <tr><th>ジュースID</th><th>自動販売機ID</th><th>ジュース名</th><th>価格</th><th>在庫</th><th>画像</th><td class="buttun-area"></td><td class="buttun-area"></td></tr>
        @if (isset($juice_list))
            @foreach ($juice_list as $juice)
                <form action="/edit" method="post" enctype="multipart/form-data">
                    @csrf
                    <tr>
                        <input type="hidden" name="id" value="{{$juice->id}}">
                        <td>{{$juice->id}}</td>
                        <td><input type="number" name="m_id" value="{{$juice->m_id}}"></td>
                        <td><input type="text" name="name" value="{{$juice->name}}"></td>
                        <td><input type="number" name="price" value="{{$juice->price}}">円</td>
                        <td><input type="number" name="stock" value="{{$juice->stock}}">個</td>
                        <td>
                            <table class="image-table">
                                <tr>
                                    <td><img name="ju_image" class="ju_image" src="data:image/jpeg;base64,{{$juice->ju_image}}" alt="image"></td>
                                    <td><input id="image" type="file" name="image"></td>
                                </tr>
                            </table>
                        </td>
                        <td class="buttun-area">
                            <input type="submit" class="upd_button" name="update_juice" value="更新">
                        </td>
                        <td class="buttun-area">
                            <input type="submit" class="del_button" name="delete_juice" value="削除">
                        </td>
                    </tr>
                </form>
            @endforeach
        @endif
    </table>
@endsection

@section('footer')
    copyright 2020 都会のエレキベア.
@endsection


・セクション機能による継承
エレキベア
エレキベア
どうして1画面なのに2つのファイルに分かれてるクマ?
マイケル
マイケル
Bladeでは「セクション」という機能を使うことで
ページを継承して作成することができるんだ!
マイケル
マイケル
書き方は下記のように

継承元で @yield を指定した箇所に対して
継承先で @section で設定する

ような使い方をするよ!
<html>
・・・略・・・
<body>
    <div class="title-area">
        <span>@yield('title')</span>
    </div>
    <div class="message-area">
        @yield('message')
    </div>
    <hr size="1">
    <div class="content">
        @yield('content')
    </div>
    <div class="footer">
        @yield('footer')
    </div>
</body>
</html>
↑継承元
@extends('layouts.juiceapp')

@section('title', ***titleに設定したい内容***)

@section('message')
*** messageエリアに出力したい内容 ***
@endsection

@section('content')
*** contentエリアに出力したい内容 ***
@endsection

@section('footer')
*** footerエリアに出力したい内容 ***
@endsection
↑継承先
エレキベア
エレキベア
これで簡単にテンプレートが作れるというわけクマね
マイケル
マイケル
そういうことだ!
システム全体で共通の構成がある場合はこうして作っておくと
他の画面の記述量も減るし、統一感もでるんだ!
エレキベア
エレキベア
これは便利クマ

・データの登録
マイケル
マイケル
データの登録エリアはこんな感じ!
入力エリアとformのアクションを記述しています!
Screenshot 2020 11 12 23 25 16

    <div class="juice-table-title">■新規追加</div>
    <table class="juice-table">
        <tr><th>自動販売機ID</th><th>ジュース名</th><th>価格</th><th>在庫</th><th>画像</th><td class="buttun-area"></td></tr>
        <form action="/edit" method="post" enctype="multipart/form-data">
            @csrf
            <tr>
                <td><input type="number" name="m_id" value="{{old('m_id')}}" min="1" max="100"></td>
                <td><input type="text" name="name" value="{{old('name')}}"></td>
                <td><input type="number" name="price" value="{{old('price')}}" min="1" max="1000">円</td>
                <td><input type="number" name="stock" value="{{old('stock')}}" min="0" max="100">個</td>
                <td><input id="image" type="file" name="image" value="{{old('image')}}"></td>
                <td class="buttun-area">
                    <input type="submit" class="ins_button" name="insert_juice" value="登録">
                </td>
            </tr>
        </form>
    </table>
エレキベア
エレキベア
大体一般的なHTMLの記述クマね
「{{old(‘XXX’)}}」と書かれているのは何クマ?
マイケル
マイケル
そこはControllerの実装で説明する入力チェックの時に、
エラーの場合にも入力値を残すための記述なんだ!
エレキベア
エレキベア
これがないと値が消えてしまうクマね
マイケル
マイケル
それから画像の登録も行うため、
formには enctype=”multipart/form-data”も記述しているよ!

・データの表示と更新
マイケル
マイケル
そしてデータの表示と更新処理は以下のような感じになっています!
Screenshot 2020 11 12 23 25 16のコピー

    <div class="juice-table-title">■テーブル情報</div>
    <table class="juice-table">
        <tr><th>ジュースID</th><th>自動販売機ID</th><th>ジュース名</th><th>価格</th><th>在庫</th><th>画像</th><td class="buttun-area"></td><td class="buttun-area"></td></tr>
        @if (isset($juice_list))
            @foreach ($juice_list as $juice)
                <form action="/edit" method="post" enctype="multipart/form-data">
                    @csrf
                    <tr>
                        <input type="hidden" name="id" value="{{$juice->id}}">
                        <td>{{$juice->id}}</td>
                        <td><input type="number" name="m_id" value="{{$juice->m_id}}"></td>
                        <td><input type="text" name="name" value="{{$juice->name}}"></td>
                        <td><input type="number" name="price" value="{{$juice->price}}">円</td>
                        <td><input type="number" name="stock" value="{{$juice->stock}}">個</td>
                        <td>
                            <table class="image-table">
                                <tr>
                                    <td><img name="ju_image" class="ju_image" src="data:image/jpeg;base64,{{$juice->ju_image}}" alt="image"></td>
                                    <td><input id="image" type="file" name="image"></td>
                                </tr>
                            </table>
                        </td>
                        <td class="buttun-area">
                            <input type="submit" class="upd_button" name="update_juice" value="更新">
                        </td>
                        <td class="buttun-area">
                            <input type="submit" class="del_button" name="delete_juice" value="削除">
                        </td>
                    </tr>
                </form>
            @endforeach
        @endif
    </table>
マイケル
マイケル
Controllerから $juice_list変数で受け取って、
for文で回して出力しています!
マイケル
マイケル
また、行ごとに更新処理を行うため、formも行ごとに定義しています。
エレキベア
エレキベア
画像の表示部分だけ少し複雑クマね
マイケル
マイケル
それは、base64で保存されている画像データを表示するために
src=”data:image/jpeg;base64,{{$juice->ju_image}}”
といった形で記述しているんだ!
エレキベア
エレキベア
画像表示は一手間いるわけクマね

Controller

マイケル
マイケル
そして最後にViewとModelを繋ぐControllerの作成だ!
下記コマンドでクラスを作成して処理を記述しましょう!
php artisan make:controller EditController
↑EditControllerクラスの作成
<?php

namespace App\Http\Controllers;

use App\Juice;
use App\Http\Requests\EditRequest;
use Illuminate\Http\Request;

class EditController extends Controller
{
    public function index(Request $request)
    {
        // Juiceテーブルのデータを取得
        $juice_list = Juice::all();
        return view('edit.index', ['juice_list'=>$juice_list]);
    }

    public function edit(Request $request)
    {
        // *** INSERT ***
        if (isset($_POST['insert_juice'])) {
            $image = base64_encode(file_get_contents($request->image));
            Juice::create([
                'm_id'=>$request->m_id,
                'name'=>$request->name,
                'price'=>$request->price,
                'stock'=>$request->stock,
                'ju_image'=>$image,
            ]);
        // *** UPDATE ***
        } elseif (isset($_POST['update_juice'])) {
            // 更新処理(画像含む)
            if (isset($request->image)) {
                $image = base64_encode(file_get_contents($request->image));
                Juice::where('id', $request->id)->update([
                    'm_id'=>$request->m_id,
                    'name'=>$request->name,
                    'price'=>$request->price,
                    'stock'=>$request->stock,
                    'ju_image'=>$image,
                    ]);
            // 更新処理(画像無し)
            } else {
                Juice::where('id', $request->id)->update([
                    'm_id'=>$request->m_id,
                    'name'=>$request->name,
                    'price'=>$request->price,
                    'stock'=>$request->stock,
                    ]);
            }
        // *** DELETE ***
        } elseif (isset($_POST['delete_juice'])) {
            Juice::find($request->id)->delete();
        }
        return redirect('/edit');
    }
}
マイケル
マイケル
index()メソッドが初期表示処理
edit()メソッドが更新処理になるよ!
エレキベア
エレキベア
edit()メソッドはごちゃごちゃ書かれてるクマね
マイケル
マイケル
これはリクエストで受け付けた後に、
submitの名前で処理を分岐しているからなんだ!

    public function edit(Request $request)
    {
        // *** INSERT ***
        if (isset($_POST['insert_juice'])) {
・・・略・・・
        // *** UPDATE ***
        } elseif (isset($_POST['update_juice'])) {
・・・略・・・
        // *** DELETE ***
        } elseif (isset($_POST['delete_juice'])) {
・・・略・・・
        }
        return redirect('/edit');
    }
↑POSTリクエストでの処理分岐
エレキベア
エレキベア
なるほどクマ
POSTリクエストの中に、送信元のsubmitボタン名が
含まれてるかどうか
見ているクマね
マイケル
マイケル
その通り!
こうすることでformの中で複数の処理を行うことができるんだ!
マイケル
マイケル
そしてModelクラスを使用したCRUD処理の部分は下記になります。

        // *** 検索 ***
        $juice_list = Juice::all();

        // *** 登録 ***
        $image = base64_encode(file_get_contents($request->image));
        Juice::create([
            'm_id'=>$request->m_id,
            'name'=>$request->name,
            'price'=>$request->price,
            'stock'=>$request->stock,
            'ju_image'=>$image,
        ]);
        
        // *** 更新 ***
        $image = base64_encode(file_get_contents($request->image));
        Juice::where('id', $request->id)->update([
            'm_id'=>$request->m_id,
            'name'=>$request->name,
            'price'=>$request->price,
            'stock'=>$request->stock,
            'ju_image'=>$image,
        ]);
        
        // *** 削除 ***
        Juice::find($request->id)->delete();

↑CRUD処理の実装(抜粋)
エレキベア
エレキベア
ここも画像ファイルの部分だけ一手間加えてるクマね
マイケル
マイケル
これも先ほどと同じで、base64に変換しているからだね。
それ以外の項目は基本的にリクエストから取得してそのまま登録・更新しているよ!
エレキベア
エレキベア
これだけでDB処理が行えるのは便利クマね

・Routeの設定(下部2行を追加)
マイケル
マイケル
Controllerに記述した処理を呼ぶために、
routesフォルダ内の、 web.phpファイルを修正します!
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('edit', 'EditController@index');
Route::post('edit', 'EditController@edit');
↑Routeの設定
マイケル
マイケル
こうすることで、
「/edit」のGETリクエストの場合にはindex()メソッドが、
POSTリクエストの場合はedit()メソッド
が呼ばれるようになります!
マイケル
マイケル
試しに
http://【サーバアドレス】/edit
でアクセスしてみると画面が表示されるはずです!
Screenshot 2020 11 14 8 05 34
エレキベア
エレキベア
画面が表示されたクマ〜〜〜〜

・バリデーションの実装
マイケル
マイケル
そして次はバリデーションを実装します!
これはViewとCotrollerの間に挟まる、
FormRequestというクラスを作成することで簡潔にチェックすることができます!
マイケル
マイケル
FormRequestクラスを下記コマンドで作成し、
処理を記述しましょう!
php artisan make:request EditRequest
↑EditRequestクラス作成
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class EditRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        if ($this->path() == 'edit')
        {
            return true;
        }
        return false;
    }

    /**
     * バリデーションルールの定義
     *
     * @return array
     */
    public function rules()
    {
        // 登録処理のみ画像設定チェックを実施
        if (isset($_POST['insert_juice'])) {
            $image_validation = ['required'];
        } else {
            $image_validation = [];
        }
        // バリデーション
        return [
            'm_id'=>'required|digits_between:1,100',
            'name'=>'required',
            'price'=>'required|digits_between:1,1000',
            'stock'=>'required|digits_between:0,100',
            'image'=>$image_validation,
        ];
    }

    /**
     * エラーメッセージの定義
     * 
     * @return array
     */
    public function messages()
    {
        return [
            'm_id.required'=>'【自動販売機ID】自動販売機IDを入力するでござる。',
            'm_id.digits_between'=>'【自動販売機ID】自動販売機IDには1以上、100以下の数字を入力するでござる。',
            'name.required'=>'【ジュース名】ジュース名を入力するでござる。',
            'price.required'=>'【価格】価格を入力するでござる。',
            'price.digits_between'=>'【価格】価格には1円以上、1000円以下の数字を入力するでござる。',
            'stock.required'=>'【在庫】在庫を入力するでござる。',
            'stock.digits_between'=>'【在庫】在庫には0個以上、100個以下の数字を入力するでござる。',
            'image.required'=>'【画像】画像を設定するでござる。',
        ];
    }
}
マイケル
マイケル
それぞれ、

・authorize()メソッド -> チェックするパスの定義
・rules()メソッド -> チェック内容の定義
・messages()メソッド -> エラーメッセージの定義
を記述します!

    public function authorize()
    {
        if ($this->path() == 'edit')
        {
            return true;
        }
        return false;
    }
↑チェックを実施するパスの設定

    /**
     * バリデーションルールの定義
     *
     * @return array
     */
    public function rules()
    {
        // 登録処理のみ画像設定チェックを実施
        if (isset($_POST['insert_juice'])) {
            $image_validation = ['required'];
        } else {
            $image_validation = [];
        }
        // バリデーション
        return [
            'm_id'=>'required|digits_between:1,100',
            'name'=>'required',
            'price'=>'required|digits_between:1,1000',
            'stock'=>'required|digits_between:0,100',
            'image'=>$image_validation,
        ];
    }
↑チェック内容の定義

    /**
     * エラーメッセージの定義
     * 
     * @return array
     */
    public function messages()
    {
        return [
            'm_id.required'=>'【自動販売機ID】自動販売機IDを入力するでござる。',
            'm_id.digits_between'=>'【自動販売機ID】自動販売機IDには1以上、100以下の数字を入力するでござる。',
            'name.required'=>'【ジュース名】ジュース名を入力するでござる。',
            'price.required'=>'【価格】価格を入力するでござる。',
            'price.digits_between'=>'【価格】価格には1円以上、1000円以下の数字を入力するでござる。',
            'stock.required'=>'【在庫】在庫を入力するでござる。',
            'stock.digits_between'=>'【在庫】在庫には0個以上、100個以下の数字を入力するでござる。',
            'image.required'=>'【画像】画像を設定するでござる。',
        ];
    }
↑エラーメッセージの定義
エレキベア
エレキベア
rules()メソッドだけ
「登録処理のみ画像設定チェックを実施」って書かれているクマね
マイケル
マイケル
これは、更新処理の時には画像参照で設定しなくていいように
個別で分岐処理を入れているんだ!
マイケル
マイケル
あとはControllerクラスの引数を「EditRequest」に変更すれば
リクエスト時にはチェック処理が実施されます!

class EditController extends Controller
{
・・・略・・・

    public function edit(EditRequest $request)
    {

・・・略・・・

    }
}
↑引数を「EditRequest」に変更する
エレキベア
エレキベア
これだけでいいクマね
エラーメッセージの表示はどうするクマ??
マイケル
マイケル
Viewのときに説明していなかったけど、
$errors変数をチェックすることでエラー有無を判断できるんだ!
マイケル
マイケル
だから下記のようにしてあげると
エラーがある場合は処理が中断されてメッセージが表示されるようになるよ!

@section('message')
    @if (count($errors) > 0)
        <span class="err_msg">
            @foreach ($errors->all() as $error)
                <div>・{{$error}}</div>
            @endforeach
        </span>
    @else
        <span class="msg">
            <div>・マスタメンテナンス画面でござる。</div>
        </span>
        @endif
@endsection

↑エラーメッセージ表示部分
エレキベア
エレキベア
これで実装完了クマね!

・文字化けの対処
マイケル
マイケル
最後に補足ですが、
formに「enctype=”multipart/form-data”」を指定している影響で、
日本語の文字が文字化けする場合があります。
マイケル
マイケル
その場合、 php.iniの文字コード指定を下記のように指定することで解消するはずです!
[mbstring]
; language for internal character representation.
; This affects mb_send_mail() and mbstring.detect_order.
; http://php.net/mbstring.language
mbstring.language = Japanese

; Use of this INI entry is deprecated, use global internal_encoding instead.
; internal/script encoding.
; Some encoding cannot work as internal encoding. (e.g. SJIS, BIG5, ISO-2022-*)
; If empty, default_charset or internal_encoding or iconv.internal_encoding is used.
; The precedence is: default_charset < internal_encoding < iconv.internal_encoding
mbstring.internal_encoding = UTF-8

; Use of this INI entry is deprecated, use global input_encoding instead.
; http input encoding.
; mbstring.encoding_traslation = On is needed to use this setting.
; If empty, default_charset or input_encoding or mbstring.input is used.
; The precedence is: default_charset < intput_encoding < mbsting.http_input
; http://php.net/mbstring.http-input
mbstring.http_input = pass

; Use of this INI entry is deprecated, use global output_encoding instead.
; http output encoding.
; mb_output_handler must be registered as output buffer to function.
; If empty, default_charset or output_encoding or mbstring.http_output is used.
; The precedence is: default_charset < output_encoding < mbstring.http_output
; To use an output encoding conversion, mbstring's output handler must be set
; otherwise output encoding conversion cannot be performed.
; http://php.net/mbstring.http-output
mbstring.http_output = pass

; enable automatic encoding translation according to
; mbstring.internal_encoding setting. Input chars are
; converted to internal encoding by setting this to On.
; Note: Do _not_ use automatic encoding translation for
;       portable libs/applications.
; http://php.net/mbstring.encoding-translation
mbstring.encoding_translation = Off

; automatic encoding detection order.
; "auto" detect order is changed according to mbstring.language
; http://php.net/mbstring.detect-order
mbstring.detect_order = auto
↑文字コードの設定
エレキベア
エレキベア
文字コードの問題はあるあるクマね〜〜〜
マイケル
マイケル
ここまででメンテナンス画面の実装は完了です!
思う存分メンテナンスしましょう!

おわりに

マイケル
マイケル
・・・と、ここまでざっと実装の解説をしましたが
いかがだったでしょうか?
エレキベア
エレキベア
情報量が多かったクマが
これだけでCRUDシステムが作れるのは楽に感じたクマ
マイケル
マイケル
分からなかったり、もっと詳細な内容が知りたいと思った方は
参考書・ネット等でがんがん調べてみてくださいね!
マイケル
マイケル
というわけで次回は最終回(予定)!
メインの購入画面を実装していくぞ!
エレキベア
エレキベア
やったるクマ〜〜〜〜!!
マイケル
マイケル
それでは今日はこの辺で!
アデュー!!

【Laravel】第二回 自動販売機システムを作ろう! 〜マスタメンテナンス画面の作成〜 〜完〜

コメント