Laravel・PHP入門

PHPer初心者

【Laravel/PHP】NULLや空文字列の判定まとめ

業務でNULL判定よく使うのでまとめ。

# 判定表

Laravel内で使っているときは
定義されていることが前提の条件文でエラーをはく。

Laravel5.5 + PHP7.1

未定義 NULL 0
if($a) error false false false
if($a == NULL) error true true true
if($a === NULL) error true false false
if($a == 0) error true true true
if($a === 0) error false true false
if($a == "") error true true true
if($a === "") error false false true
is_null($a) error true false false
isset($a) false false true true
empty($a) true true true true


例えば

<?php
public function is_null()
{
    if($a) {
        return "aだ";
    }
    return "aではない";
}

これを実行すると、Undefined variable: a
が返る。三項演算子も同様。

その代わり、

<?php

public function is_null()
{
    if(isset($a)) {
        return "aは存在する";
    }
    return "aは存在しない";
}

これを実行しても、"aは存在しない"がかえる。
issetはそもそも定義されているかどうかを判別するメソッドだからだ。


ちなみにLaravelでなく、PHPベタだとレスポンスが変わる

未定義 NULL 0
if($a) false false false false
if($a == NULL) true true true true
if($a === NULL) true true false false
if($a == 0) true true true true
if($a === 0) false false true false
if($a == "") true true true true
if($a === "") false false false true
is_null($a) true true false false
isset($a) false false true true
empty($a) true true true true

undefinedには気をつけましょう

【Laravel】ユーザの使用端末がPCかスマホか判定する(PHP)

PCとスマホ
表示項目やバリデーションを場合分けしたかったので。


Requestインスタンス
端末のデータを持ってくれている!
そこから、大概のスマートフォンの情報のみを省いて
場合分けする。

このUser-Agentが持ってるらしい。

 'agent' => $request->header('User-Agent')

なので、これを使って場合分け。

<?php

...

    /**
     * クライアントの使用端末がMobileかPCか判定
     *
     * @param $request
     * @return string
     * @access private
     */
    private function isMobileOrPc($request): string
    {
        $user_agent =  $request->header('User-Agent');
        if ((strpos($user_agent, 'iPhone') !== false)
            || (strpos($user_agent, 'iPod') !== false)
            || (strpos($user_agent, 'Android') !== false)) {
            return 'mobile';
        } else {
            return 'pc';
        }
    }

どうやら、iPoneとiPod(iPadiPodになるそうで)、後Androidを省けば
大体対応できるようです。海外はわかりませんが

以上

【Laravel】GoogleのOAuth認証でログイン機能を実装する(PHP)

LaravelのSocialiteに感動したのでメモ。

【やりたいこと】
GoogleのOAuthAPIを用いてログイン機能を実装する

※ログインのみ、GoogleAPIを用いて判定、
ユーザ情報はGoogle APIから取得する。

また、今回はuserの新規作成は割愛します。ログインのみ。
emailで管理ユーザか否か判定します。
※必要な方は、ログイン時にユーザがいなければcreateしてください。

【環境】
Laravel5.5
PHP7.2
Google API

【前提】
php artisan make:auth 実施済(なければ叩いてください)
Usersテーブル(もしくはauthに対応したテーブル)が存在する
DBは接続済み
ログインできるGoogleアカウントがある

やってみます。


Laravelは公式で、GoogleFacebookTwitterなど
様々なソーシャル認証を使用できるパッケージを持っています。(神)

Google

OAuth情報を取得・設定

この辺りは、Qiitaや記事がたくさんありますので割愛。
Google developerコンソールで、プロジェクト作成します。
Google OAuth 2.0 認証を使ったログインの実装 - Qiita
GoogleのOAuth2.0を使ってプロフィールを取得【PHP】 - FaMirror Project

・クライアントID(自動発行)
・クライアントシークレット(自動発行)
・リダイレクト先 (自分で設定)Ex.https://samplesample.jp/login/google/callback

が今後必要になります。

※redirectは、ログイン後にアクセスするURLになります。ご自身で設定ください。

※使用できるURLに制限があります!
.comや.jpなど、パブリックドメインのみ使用可能。(プライベートはlocalhostのみ)
これでかなりハマりました。。。
apacheいじって、.jpに変更したらgoogleが許してくれました。
もしgoogleから not foundなどのエラーが吐かれた場合、ここに問題ある可能性あります。

Google側の必要情報が取得できたら、
それらを認証できるよう、APIを有効にしていきます。

APIの有効化

Google のdeveloperコンソール、左側メニューのライブラリを選択。
Google Cloud Platform

Google + API
Google Drive API
・Contacts API

この3つが必要になりますので、全て有効にしてください。

f:id:fresh_engineer:20180110014305p:plain

こういうものですね。
これで、Google側の設定は完了です。

Laravelの設定

Socialiteパッケージをインストール

まずは、composerでinstallしましょう。

composer require laravel/socialite

Configの設定変更

コントローラでSocialiteを使用するため、
providerとaliasに登録しておきます。

config/app.php

<?php
Laravel\Socialite\SocialiteServiceProvider::class,

/.../

'Socialite' => Laravel\Socialite\Facades\Socialite::class,


config/service.php

<?php
'google' => [
         'client_id' => env('GOOGLE_CLIENT_ID'),
         'client_secret' => env('GOOGLE_CLIENT_SECRET'),
         'redirect' => env('APP_URL').'/login/google/callback',
],

シークレットなど隠すために、.envファイルで設定します。

.envファイル

<?php
APP_URL=(自分のwebアプリURL(上の方に既存))
...
GOOGLE_CLIENT_ID=(自分のクライアントID|新規作成)
GOOGLE_CLIENT_SECRET=(自分のクライアントシークレット|新規作成)


以上で設定が完了しました。
Controller/Model/Viewを実装します。

Laravelで実装

Route実装

まずはControllerにアクセスできるよう、Routeを設定しましょう。

<?php
// ログイン前アクセス可能(Google OAuth認証)
 Route::group(['prefix' => '/login/google', 'namespace' => 'Auth'], function ($router) {
     $router->get('/', 'LoginController@index')->name('login');
     $router->get('/redirect', 'LoginController@getRedirect');
     $router->get('/callback', 'LoginController@getCallback');
 });

Controller実装

AuthでLoginコントローラがあるはずなので、
Loginコントローラを編集します。

app/Http/Controller/Auth/LoginController.php

<?php

use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
use App\Models\User as UserModel; 
// 私はModelディレクトリ配下にUserModelを置いてるので
use Socialite; // Socialite使用可能にする

 class LoginController extends BaseController
 {
 use AuthenticatesUsers;

private $user_model;

public function __construct(UserModel $user_model)
{
    $this->middleware('guest:admin')->except('logout');
    $this->user_model = $user_model; //Usermodelをインスタンス化
}


     /**
      * エラーの有無を確認して、ログインページにリダイレクト
      *
      * @return response
      * @access public
      */
     public function index()
     {
         Auth::logout();
         return $this->render();
     }

    /**
     * Google認証ページヘユーザーをリダイレクト
     *
     * @return \Illuminate\Http\Response
     * @access public
     */
    public function getRedirect()
    {
        return Socialite::driver('google')->redirect();
    }

   /**
      * Googleからユーザー情報を取得、ログイン権限があればログイン
      *
      * @return \Illuminate\Http\Response
      * @access public
      */
     public function getCallback()
     {
         $email = Socialite::driver('google')->stateless()->user()->email;
         $user = $this->user_model->getAdminUserFromEmail($email);
         // すでに登録しているユーザとemailが一致するか確認

         if ($user === null) {
             return redirect()
                 ->route('login')
                 ->with('message', 'ログイン権限がありません。');
         }

        Auth::login($user, true); //弾かれなければ$userオブジェクトを用いてログイン
         return redirect($this->redirectTo); //ログイン後リダイレクト
      }
  }

Model実装

そしてこのUserModelでemailからユーザの有無判定。
(パスワードは使用しないので、消してしまって大丈夫です。)

<?php
     /**
      * 特定のEmailから管理ユーザを取得
      *
      * @param str $email
      * @return object
      * @access public
      */
     public function getAdminUserFromEmail(string $email)
     {
         return $this->where('email', $email)
                      ->first();
      }

Viewの実装

最後に、Viewを設定して、、、

<a href="/login/google/redirect" class="btn btn-google">Sign in using Google+</a>


ログインできれば、完了です!
な、なんて便利なんでしょう・・・!!!!涙

【Laravel入門】1.MacでLaravel5.5の環境構築する(Homestead使用)

今回は、復習がてらLaravelの環境構築。初心者向けです。

Vagrantを用いてLaravelの開発環境を構築します。
ゴールは Laravel ページにブラウザからアクセスするまで。

【環境】
Max OSX

【構築する環境】
Vagrant+VirtualBox+Homestead(PHP7.2+Laravel5.5)

Laravelに関しては、依存関係などにかかわらず構築できる
「Homestead」というboxがあるため、今回はそちらを使用します。
記載する内容は、おおよそ公式ドキュメントにも記載がありますので
合わせて参照ください。

Laravel Homestead 5.5 Laravel
インストール 5.5 Laravel

1.VagrantVirtualBoxのインストール

ブラウザからインストール

Vagrant by HashiCorp
Downloads – Oracle VM VirtualBox

Macに合わせてインストールしました。
特に編集する必要もないので、次へを押し続けてインストールを完了します。

VagrantがインストールできたかどうかはMacのターミナルを開き、

$ vagrant -v #vagrantのバージョン確認

本コマンドで、下記の返答があればOKです。(2017/12/30現在)

Vagrant 2.0.1

VirtualBoxはインストール後Application内にあります。
これでVagrantVirtualBoxのインストールは完了です。

2.Homesteadのインストール

下準備

続いて、ターミナルで操作します。(// 部分は説明なので不要です)

ディレクトリ作成

$ mkdir myapp // myappフォルダを作成(名前は任意)
$ cd myapp // myappフォルダへ移動

HomsteadのBox追加

$ vagrant box add laravel/homestead // homesteadのboxを追加

はじめに選択肢があります、今回はvirtualboxを使用するため、3を入力してEnter。
インストールがはじまります、時間がかかります(私の場合は5分程度でした)

f:id:fresh_engineer:20171230191801p:plain

完了しました!これでHomesteadのBoxがインストールできました。

(必要あれば)Xcode/Gitのインストール、非公開鍵の生成

HomesteadはGitを用いてcloneするため、

$ git --version

こちらで、git version 2.14.3など、
gitのバージョンが表示された場合はXcodeのインストールは省略ください。

もしxcrun: error: invalid〜など、エラーが出た場合は下記実行下さい。

$ xcode-select --install // installの画面が表示されるのでクリック。

XcodeをインストールすることでGitの使用が可能になります。
もう一度git --versionで確認して無事インストールできていれば完了です。

Vagrant起動時に、鍵も必要になるのでついでに生成しておきましょう。

$ cd ~/
$ ls -la I grep .ssh // id_rsa と id_rsa.pubがあればすでに生成済
(生成していない場合は) $ssh-keygen -t rsa // 質問されますがEnterでok

以上で下準備の完了です。

Homesteadのインストール

早速インストールします!
もし鍵を生成した人は、自分のディレクトリに戻りましょう。
(私の場合は cd User/自分のユーザ名/myapp)

$ git clone https://github.com/laravel/homestead.git Homestead

Cloning into 'Homestead'...
remote: Counting objects: 2743, done.
remote: Total 2743 (delta 0), reused 0 (delta 0), pack-reused 2743
Receiving objects: 100% (2743/2743), 525.83 KiB | 1.26 MiB/s, done.
Resolving deltas: 100% (1628/1628), done.

masterブランチは不安定なので、Githubのリリースページで
安定バージョンを確認し、checkoutします。

$ cd Homestead
$ git checkout v7.0.1 // 2017/12/30現在安定ver

ここまで完了したら、初期化します。

$ bash init.sh
Homestead initialized!

Homesteadの初期設定

最後に初期設定を実施します。
Homesteadの設定は、Homesteadディレクトリ内のHomestead.yamlファイルを編集します。
プロバイダから共有フォルダなど、必要あればこちらで編集ください。

そして、ローカルドメインへのリクエストをHomesteadへ転送してくれるように、
hostsファイルを編集します。

$ cd /
$ vi etc/hosts

vimでhostsファイルが開けますので、

192.168.10.10 homestead.test

このように追加すれば完了です。

Webブラウザから、こちらのIPアドレスでアクセスできます。
http://homestead.test(まだ起動していないので、接続できません)

これで、Homesteadの設定は完了です。

3. Laravelプロジェクトを作成して、Laravelページを表示する

Homesteadディレクトリ内で、以下実行します。

vagrant起動・接続

少し時間がかかります。

$ vagrant up // vagrantを起動 : 起動時に毎回必要

状況を確認します。

$vagrant status

f:id:fresh_engineer:20171230200246p:plain

起動できました。
起動後、接続します。

$ vagrant ssh // vagrantssh接続 : 起動時に毎回必要

接続できました。

ターミナルが下記のようなコマンドになっていれば接続完了です。
[vagrant@homestead ~]$


ちなみにVagrantのコマンドは下記の通り。

$ vagrant up // 起動
$vagrant ssh // 接続
$vagrant status // 状態確認
$ vagrant halt // 停止 
$vagrant reload // 再起動

Laravel インストールからブラウザ表示まで

早速、Laravelのインストールを実施します。
Homesteadは、Laravelの依存関係をすべて解決してくれるcomposerをすでに持っています。
もし持っていなければcomposer をinstallしましょう。

$composer

このコマンドで、大きくComposerと表示されればインストール済みです。
composerを用いてLaravelのインストーラをダウンロードします。

$ composer global require "laravel/installer"

インストールが完了したら、早速Composerでプロジェクトを作成しましょう!

$ composer create-project --prefer-dist laravel/laravel blog // blogは任意のプロジェクト名

こちらも少々時間がかかりますが、Laravelが便利な機能を沢山勝手に作ってくれています。

最後に、サーバを起動します。
今回、外部からの接続ができるように、最後に指定も必要です。

$ cd blog // プロジェクトディレクトリに移動
$ php artisan serve --host 0.0.0.0

そして、
http://192.168.10.10:8000/から接続してみましょう。

f:id:fresh_engineer:20171230201618p:plain


待ちにまったLaravel様!拝めた!
以上で、環境の構築は完了です。

別記事でPost投稿機能、Comment投稿機能のついたblogを作ります

【まとめ】2017年プログラミング初心者による初心者のためのおすすめ本9冊

読む順番も含めて、未経験や初心者の方に勧めたい本のまとめ。

自分が課題図書として提示された本や、周りのエンジニアの方と話していて
話に上がる本と記事をまとめました。

環境構築〜MVCフレームワーク
簡単なWebアプリケーションを作るくらいまでは
一旦本を読まずにネットで情報収集をして
(時間を短縮したい場合は
Udemyやドットインストール、paizaなどで
2000円くらいで講座購入がおすすめ)
面白ければより実践・体系的に学ぶために本などに手を出すことをオススメします。
適性や意志の強さなどにより持続するかしないかを、
時間・金銭的にもコストをかけず確認できるためです。

その後はおそらく本を読んだ方がスピードが上がる。
①〜⑨は読み返しではなく、速読だとしても初めて読む順に合わせて記載します。

おすすめの本9冊

①リーダブルコード

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

個人で勉強しているときには考え足らずだった箇所ばかりで
ソースコードは今の自分が読むものではなく、
他人もしくは数ヶ月後の自分が読むものであることを強く認識し、
その上でどのように書けば良いのかのプラクティスまで
提供してくれる本です。

オブジェクト指向でなぜ作るのか

オブジェクト指向でなぜつくるのか 第2版

オブジェクト指向でなぜつくるのか 第2版

これは最近読みましたが、もっと早く読みたかった!!と思う良書です。感動しました。
クラス、継承、ポリモーフィズムインスタンス化などあまり理解せずに
なんとなく実施していたことをなぜ、どの場所で、どのように実装すべきか、
がわかりやすく解説されています。
オブジェクト指向難しいと挫折した人、
クラスとかインスタンス化とかよくわからないけどとりあえず書いてる
という方に特におすすめです。

③入門Git

入門Git

入門Git

今のIT業界では欠かせないGit。
必要最低限も、初心者も、実際に実践しながら読めます。
初心者や未経験の人で課題が出された場合、
Gitを利用して提出することも多々あります。
時間がなければ一度速読して、
自分に必要な箇所だけ手を動かして実践すれば良いのではないでしょうか。

④チーム開発実践入門

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

飛び抜けて驚く内容が書いている、というよりは
当たり前のごとくチーム開発で必要な内容を、今の自分は全然できないんだなと思いながら
反省するチェックリストのような形で読んでました。
読みやすいので、これも速読して、実際に実装して、
もう一度読み直して納得すると身につきそう。

⑤パーフェクトPHP

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

自分の身の周りのPHPerの方ほとんどに勧められたように思います。
ただ、全部熟読するのは正直重かった。。。
一度速読して、どこに何が記載されているのか認識した上で
実践時にもう一度読むなどのやり方で私は読んでいました。

JavaScript本格入門

パーフェクトPHPと同様で、
JavaScriptの経験者には必ず勧められました。正直初心者には難しい部分も多かった。
一度ドットインストールでJavaScriptで3つくらい動くものを作りながら、
なぜそう書くのか、どういうことをしているのかを理解するために読むなどをすると
背景や理由がしっかり記載されているので、すごく腑に落ちます。
ES2015の書き方もあるのでおすすめ!

⑦基礎からのMySQL

基礎からのMySQL 第3版 (基礎からシリーズ)

基礎からのMySQL 第3版 (基礎からシリーズ)

こちらも全部を一気に読むのは少しヘビーなので
速読してそのあとは章ごとに辞書がわりに用いてました。
MySQLについては正直ネットでの検索より、
本の方が早くて分かりやすかった気がする。不思議。

⑧プロになるためのWeb技術入門

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

なぜ私たちは今自分のPCのブラウザでこれらの画面が表示、動作しているのか
全部は理解できなくても、なんとなくまず体系を知るのにすごく良書だと思いました。
今読み直したい。

⑨Webを支える技術

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

実は未経験の時に勧められて、自分の知識不足で一度挫折していました。笑
なぜ記載したかというと、ベテランの方から勧められる率がものすごく高いから。
歴史を追って背景や理由を説明してくれているので、しっかり読めればとても納得しやすい本。


いろんな本がありましたが、どれも本当に勉強になりました。。。
課題図書とおすすめ教えてくださった諸先輩がたありがとうございました。
このあとはとりあえずプリンシプルオブプログラミングと、
読み直したい本の読み直しをする予定です。

qiita.com

この記事にもあるように、学習領域を狭めることも大事ですよね、、、悩ましい、、、!


ついでに

(個人的に)買わなくてもなんとかなった本

フレームワーク(Laravel)の本

ほとんど読んでいたのは公式リファレンス、Laracastなどでした。
体系的に学ぶには良いかもしれませんが、記載されているソースコード
実践的というよりは初心者が動かすためのものなので、(例えばControllerが分厚いなど)
ドットインストールで十分だった気がします。

環境が違う本

これは実務の場合に限りますが、エンジニアになる前に買っていたPHPの本は、
自分の環境と異なっており(MAMP使用など)、全く読みませんでした。
自分の環境をちゃんと把握せず購入した自分がよくなかったです。
初心者の方は実務の前に必ず環境を細かく確認した上で買うなら買いましょう。
バージョンに大きく左右される場合も少なくない。
(Laravelなら5.2と5.5はかなり違うし、
Railsも4系と5系、Pythonも2系と3系がかなり違うように)

自分の上長や会社の考えに沿っていない本

実装の仕方はかなり人により様々。
つまりはGitのプルリクに対するコメントや指摘も様々です。
マネジメント、マネジメントされる側双方のコストを減らすため
できれば自分の上長予定の方などからおすすめの本5冊くらい教えてもらいましょう。


オブジェクト指向でなぜつくるのか、を読んだときは本気で感動しました。
ちなみに森岡さんのこの本を読んだときと同じくらい感動しました。

考え方で一番好きな本。確率思考の戦略論もおすすめ。

以上、初心者による初心者のためのおすすめ本でした。
少しでも未経験や初心者のエンジニアの人がエンジニアになれますように!

【Laravel】多対多のリレーションまとめ

参考:
Eloquent:リレーション 5.5 Laravel


今回は、例えばブログのカテゴリーのような、お互いが複数関わる
Laravelの多対多の関係について言及します。
個人的にはかなりハマりましたが言及された記事が少なかった。

Laravelの多対多関係について

ブログのカテゴリー、学校の学生と科目など、ブログが多くのカテゴリーを持ち、
カテゴリーも多くのブログを持つ(この記事もLaravelや多対多、Eloquentなど多くのカテゴリを持ちます)
ような関係の事を示しています。
今回はあるエントリーとカテゴリーを例にして言及することとします。

公式ドキュメントにも記載がありますが、1対1や、1対多より少し複雑です。
2つをつなぐ中間テーブルが必要になるからです。(モデルは必要ありません)
早速実装してみます!

中間テーブルやModelを作ってみる

今回の場合、categories、entries、そしてcategory_entryテーブルを使用します。
命名規則により、多対多関係になるテーブルの単数系をアルファベット順に並べます。
(無視してもできるそうですが、かなり面倒らしいので避けることをお薦めします。)

DBの構成

  1. entriesテーブル
  • id
  • title
  • body
  • created_at
  • updated_at
  1. categoriesテーブル
  • id
  • name
  • created_at
  • updated_at
  1. category_entryテーブル(中間テーブル)
  • id
  • category_id
  • entry_id

中間テーブルについては、1つの関係につき1つのデータになりますので
このブログの記事で例をあげると、
f:id:fresh_engineer:20171209184159p:plain
この記事のidが9の場合、下記のようになります。(多いので4つに省略しています)
f:id:fresh_engineer:20171209185737p:plain:h100

つまり、1つの記事に対して4つのカテゴリが対応している場合、
4つのデータが必要になります。

DBにテーブルが登録できれば、次はmodelを作成していきます。

Modelの生成

中間テーブルについてはModelを必要としませんので、
Entryモデル、Categoryモデルを生成します。
まずはリレーション生成の部分のみ。

App\Models\Category.php

<?php

class Category extends Model
{
  public function entries()
  {
    return $this->belongsToMany('App\Models\Entry::class');
  }
}

App\Models\Entry.php

<?php
class Entry extends Model
{
  protected $fillable =
  [
    'title',
    'body',
  ];

  public function categories()
  {
    return $this->belongsToMany('App\Models\Category::class');
  }
}

今回は、多対多のため、belongsToManyメソッドを呼び出します。
準備はこれでOKです。

実践で、MVCモデルを利用した上で、データを入力する部分まで実装します。
カテゴリーは既にDBへ登録済みの前提で、
記事を投稿する時にカテゴリーの選択ができるような形で実装します。
(Viewはtwigを使用してますのでよしなに変更ください)

Controller/Model/View実装

View実装
<div class="container">
<form action="/entry/complete" method="post">

<div class="form-group">
    <label for="f-title">Title</label>
    <textarea name="title" class="form-control" id="f-other"></textarea>
</div>

<div class="form-group">
    <label for="f-category_ids">Category</label>
    <select name = "language_ids[]" class = "form-control" id = "f-language_ids" multiple>
    {% for id, name in all_categories_list %}
    <option value = "{{ id }}" >{{ name }}</option>
    {% endfor %}
    </select>
</div>

<div class="form-group">
    <label for="f-body">body</label>
    <textarea name="body" class="form-control" id="f-body"></textarea>
</div>

<div class="form-group">
    <input type="submit" value="send" class="btn" id="btn">
</div>

</form>
</div>
Controller実装

EntryControllerで入力フォームを表示する際、
既に登録済みのカテゴリーも表示します。
そして、Entryデータを保存する際に、
Entryデータと対応したカテゴリーのデータを保存するメソッドを呼び出します。

App/Controllers/EntryContoroller

<?php
public function input(Request $request) //入力のViewを表示(その時にカテゴリーの配列も渡す)
{
         return view('entry/input',
         [
                 'all_categories_list' => $this->getAllCategoriesList()
         ]);
         }
}

public function complete(Request $request)
{
         $inputs = $request->all(); 
         $category_ids = $inputs['category_ids'];
         unset($inputs['category_ids']); //fillableしているのでEntryテーブルに入らないカラムは除く

         $id = $this->entry_model->saveAndGetId($inputs);
         $this->entry_model->saveCategoryIdsFromEntryId($id, $language_ids);
         return view('entry/complete');
}
Model実装

App/Models/Entry.php

<?php
namespace App\Models;

use App\Models\Language;
use Illuminate\Database\Eloquent\Model;

class Entry extends Model
{
  protected function $fillable
       [
            'title',
            'body',
  ];

  public function saveAndGetId($inputs)
  {
          return $this->create($inputs)->id;
               //entryデータを生成した上で、中間テーブルに必要なIDを取り出す
  }
       public function saveLanguageIdsFromEntryId(int $id, array $language_ids){
            $entry = $this->find($id); //idからEntryを取り出して、
            return $entry->languages()->attach($language_ids);
            //ここで中間テーブルに保存!
        }


App/Models/Category.php

<?php
namespace App\Models;

use App\Models;
use Illuminate\Support\Collection;

class Category extends Model
{
    public function getAllCategoriesList()
    {
        return $this->pluck('name', 'id'); //すべてのカテゴリーを配列にして取り出す
    }

※関係の定義の部分は既出なので省略。


route/web.php

<?php
    Route::post('/entry/conplete' => 'EntryController@complete');

以上

【Laravel】ViewにMeta情報を渡す共通処理を実装する

話は飛躍しますが復習メモ。

DRY(Dont Repeat Yourself)の法則に則り、
共通処理や共通の変数については、何度も呼び出すのではなく
1度処理できるようにすると良い。

例えば、今回は全てのViewにHTMLへ埋め込む
Meta情報(titleやページ情報)を、共通処理にしたいとします。
Viewを呼び出すにあたり、共通経路はいくつかありますが
(親クラスやRouteなど)

auth認証など、毎回呼び出すものはMiddlewareが確実であり簡潔なので
全てのViewにデータを渡したい今回は
MiddlewareとView::shareメソッドを採用します。

※今回はDBにMeta情報全て入力済み、
MetaModelとmeta table使用の前提で進めていきます。

Middlewareを実際に作って、通し、実装する

①Middlewareを作る

php artisan make:Middleware GetMetaData //キャメルケース

緑色でsuccessと出ると、app/Http/Middlewareの下にGetMetaData.php
作成されているはずです。

②Middlewareを通す

Middlewareを使用するために、Kernel.phpで定義します。

今回は全てのViewに渡すとき、
つまりほとんどのHTTPリクエストに対応したいため
限定しない$middlewareプロパティへ追加します。

Kernel.php

protected $middleware = [
  ...
   \App\Http\Middleware\GetMetaData::class //追加
];

これで、全てのHTTPリクエスト時にGetMetaDataという
Middlewareが実行されるようになりました。

③Middlewareを実装する

それでは早速GetMetaDataの内容を実装していきます。
App/Http/Middleware/GetMetaData.php

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View; //今回はView::shareを使用するので
use App\Models\Meta as MetaModel;

class GetMetaData 
{

public function __construct()
{
  $this->meta_model = new MetaModel; //MetaModelをインスタンス化
}
public function handle(Request $request, Closure $next)
{
View::share(['meta' => $this->meta_model->getMetaData($request)])
//全てのViewに、metaという名前の配列を渡す
ValueはMetaModelのgetMetaDataメソッドを呼び出す
return $next($request);
}

Meta.php

public function getMetaData($request)
{
  $meta_id = $request[meta_id];
  return $this->where('meta_id', $meta_id); 
}

これで、Viewを表示するたびに
MetaテーブルからMeta情報を抽出する一連の流れが実装できました。


以上です。

参考:
ミドルウェア 5.5 Laravel