「あれってLaravelではどうやるんだっけ?」という時のHowTo一覧

Laravel

今まで割とピュアなPHPでやってた人が、いざLaravelフレームワークに移行した時に、

「あの機能が必要なんだけど、あれってLaravelではどうやるんだ?」

という場面に出くわしがちです

(ですよね?、よね?)

そんな時のためのやり方一覧です

対象はLaravel7になります

ルーティング関係

引数(パラメータ)を持ったURLの指定

https://hoge.com/post/3

という様なGETパラメータ付きのURLをルーティングに指定し、その値を受け取る方法

// ルーティング
Route::get('post/{post_id}',  'PostController@index');
// コントローラ (このメソッドの引数に、ルーティングで指定した変数名を指定)
public function index($post_id){
 
    // ルーティングで指定した変数名で値を取得できる!
    echo $post_id;
 
}

コントローラー関係

コントローラーからビューに変数を送る

コントローラー内で処理した変数をビュー側に送りたい場面は多いですよね

そんな時はcompact()を使います

// コントローラ 
public function index(){
 
    // ルーティングで指定した変数名で値を取得できる!
    $name   = "ヒトミ";
    $groups = ['メグミ','ケン','ヒロ'];
 
    return view('stories',compact('name','groups'));  
    
}
<!-- 変数 -->
<div>
    {{ name }}
</div>
 
<!-- 配列 -->
<div>
    @foreach ($groups as $value)
        {{ $value }}
    @endforeach
</div>

注意点としては、compactでは変数を文字列で指定します。先頭のドルマークは外します。

Blade関連

URLエンコード/デコード

<div>
  {{ urlencode('エンコードしてぇえええ') }}
  {{ urldecode('デコードしてぇえええ') }}
</div>

文字列の結合

<div>
  {{ 'このページは' . $pageNo . '目です' }}
</div>

認証関係

Laravelには簡単にユーザ認証できる機能がついていますから、基本的にはこれを利用します

テーブルの変更

デフォルトでは「users」テーブルをユーザ認証に利用しますが、このテーブル名を変更する方法

config/auth.phpにある以下の箇所を変更します

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\OrenoUser::class,
    ],
],

modelのところを、変えたいテーブルのモデルに変更します

DB操作関係

検索(Select)

プリペアードステートメントを使った検索

ピュアPHP

僕が独自に定義した関数を呼び出す場合ですが、だいたい今まではこんな感じでデータベースの検索をしてました

// DBからユーザを検索
$result  = $db->select("SELECT `name` FROM `user_table` WHERE `id` = ?",[5],"i");
 
// 名前を表示
echo $result['result'][0]['name'];

毎回毎回、結構ガッツリとSQLクエリーを書くのがしんどいです

全く同じ検索をする場合をLaravelで書いた場合と比較してみましょう

Laravel(その1)

// DBからユーザを検索
$result  = DB::select('SELECT `name` FROM `user_table` WHERE `id` = ?',[5]);
 
// 名前を表示
echo $result[0]->name;

DBファサードを使ってますが、ガッツリとクエリーを書くという点においてはあまり変わりません

Laravel(その2)

// DBからユーザを検索
$result  = DB::table('user_table')->where('id', 5)->get();
 
// 名前を表示
echo $result[0]->name;

クエリービルダーを使ってるので、だいぶスッキリしました

簡単な検索程度なら、むしろこっちの方が可読性も高くて良さそうです

Laravel(その3)

// 3-1.DBからユーザを検索
$result  = UserTable::find(5); // 主キーで検索
// 名前を表示
echo $result->name;
 
// 3-2.DBからユーザを検索 
$result  = UserTable::where('name', 'hitomi')->get(); // 条件を指定
 
// 3-3.DBからユーザを検索(条件を複数指定)
$result  = UserTable::where('name', 'hitomi')->orwhere('height','>',163)->get(); // 条件を指定
 
// 名前を表示
echo $result[0]->name;

Eloquentを使うことで、非常にスッキリかけてます

ちなみにfind()の変わりにfindOrFail()を使うと、検索結果が見つからなかった時に自動的に404を表示してくれます

なお、find()の引数にはテーブルの主キーの値を指定します。get()とは返却値が異なることに注意

挿入(Insert)

ピュアPHP

// ユーザを挿入
$result  = $db->upInDelProc("INSERT INTO `user_table`(`name`) VALUES(?);",['ヒトミ'],"s");

Laravel(その1)

// 1-1.ユーザを挿入
DB::table('user_table')->insert(['name' => 'ヒトミ']);
 
// 1-2.ユーザを挿入(idを取得する場合)
$id = DB::table('user_table')-> insertGetId(['name' => 'ヒトミ']);
 
// インサートしたid
echo $id;

Laravel(その2)

// ユーザを挿入
$data = UserTable::create(['name' => 'ヒトミ']);
 
// インサートしたid
echo $data->id;

Laravel(その3)

// ユーザを挿入
$user = new UserTable();
 
$user->name = 'ヒトミ';
$user->save();
 
// インサートしたid
echo $user->id;

Laravel(レコードがなかったら挿入)

// 初めてのユーザだったら挿入
UserTable::firstOrCreate(['name' => 'ヒトミ']);

引数で検索し、もし該当のレコードがなかったら挿入します

ピュアなPHPだったら一回Selectして、結果がなかったらInsertする流れになるので、firstOrCreateを使うととても簡単に記述できます

更新(Update)

Laravel(その1)

// 1.ユーザを更新
UserTable::where('id', 3)
->update(['name' => 'ヒトミ']);

現状のデータと差分があろうがなかろうが更新される

Laravel(その2)

// ユーザを更新
$user = UserTable::find(3);
 
$user->name = 'ヒトミ';
 
$user->save();

差分がなかったら更新されない

更新もしくは挿入

レコードがなかったら挿入(Insert)し、レコードがあったら更新(Update)する処理

ピュアPHP

// ユーザを挿入(もしくは更新)
$result  = $db->upInDelProc(
    "INSERT INTO `user_table`(`id`,`name`) VALUES(?,?) ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);",
    [5,'ヒトミ'],
    "is"
);

MySQLでは「ON DUPLICATE KEY UPDATE」句を使って実現します

クエリーの構文自体はそこまで複雑ではないんですが、これをいちいち書くのは割と面倒な作業です

Laravel

// ユーザを挿入(もしくは更新)
UserTable::updateOrCreate(
    ['id'   => 5],        // このキーがあればUpdate、なければInsert
    ['name' => 'ヒトミ' (,'no' => 3)]
);

LaravelのupdateOrCreate()を使うと、ここまでスッキリと書くことができます

削除(Delete)

ピュアPHP

// ユーザの削除
$result  = $db->upInDelProc(
    "DELETE FROM `user_table` WHERE `id` = ?;",[5],"i"
);

Laravel(その1)

// ユーザの削除
$user = UserTable::find(5);
 
$user->delete();

Laravel(その2)

// ユーザの削除
UserTable:: destroy(5);

Laravel(その3)

// ユーザの削除
UserTable::where('id',5)->delete();

トランザクション処理

// トランザクションを開始
DB::beginTransaction();
 
// 挿入・更新処理など
UserTable::create(['name' = 'mariko']);
 
// ロールバック
DB::rollback();
 
// コミット
DB::commit();

セッション

保存

session([
    'name'    => 'tarou',
    'address' => 'tokyo',
]);

取得

$name    = session('name');
$address = session('address');

存在チェック

値の存在チェックにはexists()とhas()があります

この両者の違いはnullの扱いにあります

exists()はnullであっても存在してる場合はtrueを返し、

has()はnullだとfalseを返します

入力値exists()has()
123truetrue
“"truetrue
nulltruefalse
if ( session()->exists('name') ) {
    // 存在した!
}

if ( session()->has('name') ) {
    // 存在した!
}

削除

// 個別
session()->forget('name');
 
// 全て
session()->flush();

Vue.js関係

値をエスケープしないで表示する

Blade + Vue.jsでVue変数の値をエスケープしないで表示

// エスケープあり
<div>@{{ name }}</div>
 
// エスケープなし(やりがちな失敗例)
<div>@{!! name !!}</div>
 
// エスケープなし(正解)
<div v-html="name"></div>

View( Blade )からVueコンポーネントへ値を渡す

コントローラ → View(Blade) → Vue へと変数を渡していくリレー

// View(Blade)
 
<div id="app">
    // Vueへ送るパラメータをセット ($MyNameはコントローラから送られた変数)
    <example-component name="{{ $MyName }}"></example-component>
</div>
// Vue
 
<template>
    <div>
        //  View(Blade)から送られてきた変数を出力!
        {{ name }}
    </div>
</template>
 
<script>
export default {
    // Viewから送られてくる変数名を定義
    props: ['name'],
};
</script>

Vueのpropsで受け取った変数をmounted()内で使う

View(Blade)からpropsで受け取った変数を、Vueのmounted()内で使用する

<script>
export default {
    props: ['name'],
    mounted() {
        // this + (propsで指定した)変数名でOK
        console.log( this.name );
    }
};
</script>

Vueでclassなどの属性に変数を追加

動的に変化するhtmlでは、名前の重複を防ぐためにname="radio_1″みたいな連番をつけたいことがあります

例えばclass属性に特定の文字列と変数を結合する方法

// 変数noはvueファイル内で有効な変数
<button :class="'radio_' + no "></button>

JSやCSSの外部ファイルをWebPack(Mix)として追加

いまいちなやり方

ライブラリなんかのJSファイルを別途追加したい時に、public/js配下にファイルを設置して、Bladeファイル上で、

<script src="/js/hoge.js"></script>

のように読み込んでもいいんですが、せっかくLaravel Mixを使ってるのでapp.jsに含めてしまいたいじゃないですか

スマートなやり方

そんな時は、resourcesフォルダ配下にassetというフォルダを作ってそこにファイルを配置します

resources
 |–asset ← これを追加
  |–js ← これを追加
   |–hogejs.js← このjsファイルを追加したい
  |–css ← これを追加
   |–hogecss.css← このcssファイルを追加したい

jsとcssフォルダを追加してますが、その辺はお好みで

jsファイルの読み込みを指示

あとはresources/js/app.jsファイルで読み込みを指示します

require('./bootstrap');
require('../asset/js/hogejs'); // 読み込んでぇええ

window.Vue = require('vue');

cssファイルの読み込みを指示

同様に、cssファイルを読み込むためにはresources/sass/app.scssファイルで読み込みを指示します

@import "../asset/css/hogecss"; // 読み込んでぇええ

ビルド

$ npm run dev

最後に忘れずにビルドを実行しましょう

こうすれば、追加したいファイルをpublic/js/app.jsやapp.cssに含めることができます

CSS関係

Laravel Mixを利用してCSSの装飾を変更する場合や、Bootstrapをカスタマイズしたい場合

デバッグ

$names = [ "ヒトミ", "メグミ", "ケン" ];
 
// PHPのvar_dump()を綺麗にフォーマットして表示
dump( $names );
 
array:3 [▼
  0 => "ヒトミ"
  1 => "メグミ"
  2 => "ケン"
]
 
// dump and dieの略
dd( $names );
 
array:3 [▼
  0 => "ヒトミ"
  1 => "メグミ"
  2 => "ケン"
]
 
// これ以降は実行されない

バリデーション

Post送信時の値チェック

// Post送信時に呼ばれるコントローラ内メソッド
public function store(Request $request)
{
    // バリデーションの生成
    $validation = Validator::make(
        $request->all(),
        [
            'name'  => 'required|min:5|max:10',
            'email' => 'required|email', 
        ],
        [
            'name.required'  => '名前は必須です。',
            'name.min'       => '名前は5文字以上必要です。',
            'name.max'       => '名前は10文字以下です。',
            'email.required' => 'メールアドレスは必須です',
            'email.email'    => '有効なメールアドレスを入力して下さい。',
        ]
    );
 
    // エラーあり (入力ページへ戻る)
    if ($validation->fails()) {
        return redirect()->back()->withErrors($validation->errors())->withInput();
    }
 
    // エラーなし
}
{{-- エラーを表示 --}}
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

Validator::make()の第3引数は指定しなくても大丈夫ですが、その場合エラーメッセージが英語になります

そのほかのバリデーションルールはこちらをご覧ください

エラー表示

// 403ページを表示
abort('403');

// 404ページとカスタムメッセ=時を表示
abort('404', '不正なURLです。');

マイグレーションを利用しない

複数人で開発する場面では何かと便利なマイグレーション機能ですが、個人一人で開発するには別に使わない(要らない)こともあります

Laravelではマイグレーションを実行しなくてもWebサイトを開発することはできますが、モデルは定義しておく必要があります

またマイグレーション機能を実行しないので別途、DB側で手動によるテーブル作成が必要になります

モデルを作る

$ php artisan make:model User

テーブルを定義する

上記のコマンドを実行すると、app配下にモデルファイル(User.php)が作成されるので、そこでテーブル情報を定義します

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
    protected $table = 'user_table';
 
    protected $fillable = [
        'id', 'user_name', 'update_at', 'create_at'
    ];
}

定数クラスの追加

ハードコーディングを避けるために、定数クラスが欲しいですよね

Laravelでは定数クラスにconst.phpを使います

config/const.phpを以下の様に編集します

設定

<?php

return [
    'SITE_NAME' => "mof mof",
];

使い方

$siteName = config('const.SITE_NAME');
echo $siteName;

viewファイルからも呼び出し可能です

<p>
  {{ config('const.SITE_NAME') }}
</p>

注意

php artisan serveを使ったローカル環境の場合、以下のコマンドを叩かないとconfigファイルへの更新が反映されません

$ php artisan config:clear

自分で作った独自の自作メソッドを使う

Laravelにはファサードを始め、便利なライブラリがたくさんあります

しかし時として、自分で作った独自の関数を使いたい時もあります。そんな時のやり方です

自作関数ディレクトリの作成

まず、appフォルダ配下に自作関数用のディレクトリを作ります

app
 |–Functions ← これを追加

関数クラスの作成

あなただけのオリジナリティあふれる関数を余すことなく定義します

<?php
 
namespace App\Functions;
 
class PostFunc
{
  public static function getSuperID()
  {
     return 3;
  }
}

エイリアスを登録

コントローラー以外で呼び出したい場合は、エイリアスにも登録しておきましょう

config/app.phpの「aliases」に以下を追加します

<?php
  
  'aliases' => [
    ~~~~~~ 省略 ~~~~~~~
    'PostFunc' => App\Functions\PostFunction::class,

呼び出す

あとは好きな場所で呼び出すだけです

<?php
namespace App\Http\Controllers;
use PostFunc;
 
class BooksController extends Controller
{
    public function index()
    {
        $id = PostFunc::getSuperID();
        echo $id;
 
        return view('index');
    }
}

数字などのパラメータを暗号化する

会員IDやページ数などの数字をそのままURLに使ってしまうと、外部からユーザ数などの規模感などがもろにバレてしまいます

例:https://hoge.com/user/12

理想:https://hoge.com/user/fh32hkl

そのためURLのパラメータにあたる部分を暗号化したいのですが、LaravelのCryptファサードは非可逆なため復号化することができません

URLのパラメータは正直なところ、パスワードみたいに絶対にバレちゃいけないレベルのものではないので、もっと手軽な暗号-復号化の機能が欲しいところです

そこで、Hashidsを利用します

インストール

$ composer require hashids/hashids

使い方

use Hashids\Hashids;
 
$hashids = new Hashids();
 
// 暗号化 → h23lkf23lkjfwa
$hash = $hashids->encode(12);
 
// 復号化 → 12
$hashids->decode($hash);

そのほかの詳細はこちらをご覧ください

Font Awesome

$ npm install @fortawesome/fontawesome-free --save
@import '~@fortawesome/fontawesome-free/scss/fontawesome';
@import '~@fortawesome/fontawesome-free/scss/solid';
@import '~@fortawesome/fontawesome-free/scss/regular';
@import '~@fortawesome/fontawesome-free/scss/brands';
<i class="fab fa-twitter"></i>