Laravel・PHP入門

未経験Ruby->PHPer初心者

【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>


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

【まとめ】25歳の文系女子が未経験からエンジニアになった話

エンジニアになることが決まり、また実際にエンジニアになった後も
この辺りの質問をいただくことが非常に多いため
今回ブログにまとめることにしました。

・なぜエンジニアになったのか
・エンジニアになるまでに何をしたのか
・実際エンジニアになってみてどうだったか


未経験でエンジニアになりたいけど何をすればいいかわからない人の
一助になれば幸いです。

自己紹介

2015年4月〜2016年9月(新卒) 文系の大卒、大手で販売職
〜2017年10月(転職) IT専門のキャリアアドバイザー
〜今 エンジニアになる(約2ヶ月)
経歴としてはこんな感じです。

スクールには通わず、
平均でいうと月80時間くらい残業をしながら
下記内容を実施しています。

スクールに通わず未経験で色々実施できたのは、

・エンジニアが周りに多かった
・そもそもIT専門のキャリアアドバイザーなので
 未経験の市場感なども認識していた
・運が良かった

今となっては本当に恵まれた環境でした。。。
周りに感謝しかない。


身バレを恐れず今回は赤裸々に語ります。

なぜエンジニアになったのか

OSSという文化に感動したから

8割これに尽きます。
今まで販売・営業と経験してきて、この文化には本当に驚きました。
目的幅広いですが、世界が、競争や損得だけでなく、皆で前に進んでいる姿が大好きです。

なれると思ったから

実は、今年の6月くらいまではなんとなくなりたいなあ、
というイメージで勉強を続けていました。
ですが、エンジニアになることを決断するきっかけがありました。

知人エンジニアのこんな会話でした

「エンジニアにならないの?」
「なりたいとは思うけど、なれるのかな、とも思う」
え、なれるよ
「だって俺がエンジニアになったの25歳だし」
「同い年だし」
なれる

ああ、そうか、なれるのか。私エンジニアになれるんだ。
断言されてはじめて、小心者の私はなることを決断できたのです。
我ながら情けない話です。でもこの時に背中を押してくれたのはこの断言です。

「じゃあ、なるためには今から何をしようか」

こうして、
「エンジニアになりたい」
→「なれる」
→「なるためにはどうすればいいか」
という発想へ変わります。

エンジニアになるために何をしたのか

時系列で追います。(期間は目安)

社内エンジニアの勉強会に参加して環境構築(2017年1月〜3月)

エンジニアの方が非エンジニア向けに
Railsで簡単なブログを作る
勉強会を週1で開催してくださっていました。
まだエンジニアになれると思ってなかった頃です。

先生が書いたコードをそのまま写経するというものでしたが、
rails new blogで全部ファイルが勝手にできる姿を見た時には
本当に驚いたことを覚えています。

【やったこと】2ヶ月週1:1時間(写経)

MVCCRUDの簡単な理解
AWSでサーバ借りる
WindowsTeraTermから接続
Ruby/Rails/Apache/MySQLも入れて環境構築
・ 簡単なテーブル作成
・ Postしたデータを表示するところまで

このときは、実際に考えたというよりは完全に写経だったので
エンジニアってこんなことしてるんだレベルの理解でした。
同じことをして、と言われてもできなかった。

諸事情から一度勉強会が頓挫します。

社内エンジニアに課題をもらう(3月〜4月)

エンジニアになりたいと漠然と思い始めていました。
ですがこのときはまだ覚悟はできていませんでした。
なんとなくなりたいなあ、くらい。

同先生に依頼し、個別で勉強会の相談時間をいただきます。
1週間に1回時間をいただき、もらった課題を実施してくる
というような流れでした。

【やったこと】1ヶ月週2:平均4時間前後(自力+質問/試行)

・自力でVagrant + VirtualBoxを利用し開発環境の構築
(CentOS7/Laravel/Apache/MySQL/PHP)
・正規化を意識したテーブル・カラムの作成
・Postを投稿したら、それが表示される
・URLに/show/1と入力した時にid=1のpostデータが表示される

主にこの辺り実施しました。
ここで初めて、写経じゃなくて自分で調べる・考える
というところに近づきます。

ドットインストールやUdemyで写経する(5月〜6月中盤)

諸事情により(笑)この辺りから独学の比重が増えます。
独学でできることをやろうと考えてました。

【やったこと】1ヶ月週2:4時間(動画学習による独学)

・PaizaのPHPRubyの基礎一通り
・ドットインストールみて環境構築
・UdemyみてPythonニューラルネットワーク作る

正直独学だと迷走するので(笑)何をやるかは相談すべきだった。
逆に全く知らなかったPythonとかにも手を出した。
何もわかってない時に写経の幅を広げたところで
なるほど〜動いた〜にはなるけど、その先は足りなかった。
未経験の時は裾を広げすぎるべからず。

qiita.com

この記事にもありますね。

社外エンジニアに課題をもらう(6月後半〜7月)

そのように少し停滞していましたが、転機が訪れます。
自分が支援したエンジニアさんと仲良くなり
仕事としてエンジニアになることを決断します。
(なぜエンジニアになったのか、の会話に出てきたエンジニアさんです)

中期目標・短期目標の設定をする
その目標達成のための課題にアドバイスしてくれることに。

【やったこと】2ヶ月週3,4:平均20時間程度

(動画学習:写経→課題:自分で考える)
・環境構築:さくらのVPS+CentOS7+Rails4系+Ruby2.3系
・ドットインストールでToDo管理アプリ(上と同じ環境)
・ToDo管理アプリの機能拡張
APIの拡張
①itemの新規作成・表示・削除・更新
②itemをidではなく名前やpriceなどで検索できるAPI作成
③itemにカテゴリをつける
④カテゴリにひもづくitemsを取得するAPI作成
⑤itemをカテゴリに紐づかせて新規作成するAPI
⑥.itemのカテゴリのみ変更するAPI

▼認証
1.認証機能(新規登録・ログイン)を作る
2.作った認証機能を元に各ユーザーにトークンを付与する
3.正規のトークンを持っている人だけ上記で作ったAPIを利用できるようにする

JavaScript
1.JavaScriptAjaxを使って、上記で作ったAPIを利用してみる
2.帰ってきたJsonを元にJavaScriptでHTMLを作成し表示させる

このようにして、土日ひたすらいただいた課題を実施して行くことに。
ここにきて初めて、
自分が今まで実施してきたことがほとんど写経であり
「自分で考えて理解・実装」ができていなかったことに気づきます。
2ヶ月間これらを実施することで
自分で考えることの難しさと面白さを知り、
エンジニアになるということが現実味を増します。

エンジニアインターンや選考を経験する(8月〜10月)

さて、次のフェーズはどうすれば
「職業:エンジニア」になれるかでした。
結論から申し上げますと、
「より実務に近い経験を積むこと」
「未経験採用」を前提としている環境を選択肢に入れること
ここから、無給インターンにチャレンジすることにします。

というのも、通常の第二新卒なら転職で何ら問題ありません、
私には1点問題があったのです。
ジョブホッパー」という日本の転職市場において大きく関わるレッテルです。
1年半で前職を退職し、今回も約1年で職種変更に乗り切ろうとしていました。
教育投資してもすぐに職種変更や転職されるのであれば
企業が採用・教育する理由がありません。
お恥ずかしい話ながら、私はエンジニアという職種を理解するまで、自分のやりたい仕事をみつけられていなかったのです、、、

教育・採用コストを減らす・差別化するを目的に
無給インターンを選びました。

ありがたいことに、
インターンについては嬉しいお話をいただくこともあり
下記内容を実施しました。

【やったこと】2ヶ月週2〜4:20時間程度

インターンなど選考(選考課題含む)
Rubyの基礎(配列やハッシュなど全くわかってなかった)
・html、CSS、JSの基礎
・(並行して課題)

機密事項は話せませんが、すごく勉強になりました。

※ 勿論全てうまく行っていた訳ではなく
書類不合格だったり、
人事か営業なら内定を出すが
エンジニアとしては不合格、
の結果もありました。

エンジニアになった

結果として、
あるご縁をいただき11月からエンジニアになりました。
もうここまでお世話になり尽くした人に感謝しかできません。

とにかくいただいた投資に対して、自分ができることで
お返ししていくつもりです。

なるまでに必要だったと思うこと

自分の活動などこれまでの経緯を通して、
大事かなと思うポイントまとめ。

エンジニアになる覚悟と好奇心

これがないと続かないし行動できません。

とりあえず行動すること

やりたい〜やれない〜
→本当にやりたいなら何かやりましょう

全力で教わること

教えてもらった時には礼儀として全力で応えるべき。
相手の時間をもらう分、課題は上回るくらい実施すれば
きっと次の課題をもらえるはずです。
あと気を遣いすぎて質問しなくてできない・やれない人もそこで止まる
課題をもらったからにはやる、できないなら聞くまでするべきです。

適切な時期に、適切な課題を実施すること

これが意外と大事だなと思いました。
ブラウザって何?環境??という人に
ブログでログイン機能作ろう〜と言っても、きっと挫折します。

ポテンシャルを評価対象に載せること

(裏話)未経験エンジニアってドットインストールや本、チュートリアル
スクールに通って、1つ何かを作る、まではできる人が多いです。
同じコードだから差がわからない=お見送りに繋がりやすいです。

企業に書類を提出した時に企業はどう見えるか?
ドットインストールレベルだなあ」これです。これに尽きてしまうのです。
実務のコーディングは性格が全く違う
だからどう考えていて、どんなポテンシャルあるか知りたい。

なので、プロセスを、もしくは他人と違う形でアウトプットしてください。
・なぜこのアプリを作ったのか
・いつ何をどう考えたのかなぜそうしたのか
・自分で考えて作ってみる
この辺りは本当に意識したほうが良いと思います。

企業は学校ではなくビジネスであること

これもめちゃくちゃ大事だなと思いました。
自分がエンジニア採用される場合、月25万、
おそらく3ヶ月〜半年はほとんど稼げないことを自覚して
自分を採用するメリットがどこにあるのか考えたほうがいい。

実際なってみてどうだったか

最後に、実際にエンジニアになって2ヶ月たったので
感想まとめ。
(ただし今の環境が死ぬほど良いので、
他の環境だとまた感想が変わってくると思います)

楽しすぎる

驚くぐらい楽しいです。週7で20時間ずっとエンジニアリングしていたいくらいです。

どうすれば期待通り動くか問題を解くのが楽しい

これは性格もありますが、少し難しい問題があってそれが解けた瞬間すごく楽しい。笑
この機能作りたいな、どうすれば作れるんだろう、作ってみる、作れた、楽しい!の繰り返し
逆に課題もらって解けた時に楽しくない人はエンジニアやめたほうがいいです。

コードレビューもらえるのが楽しい

こうやって書けばいいんだ、何これこんな書き方あるんだ、も楽しい。
なぜその指摘が入るのか、想像して、あってるか先輩に確認すると
想定通りだったり、全く想定外でそんなこと考えてるんですか!?って
なったりするのが楽しいです。

エンジニア文化にひたすら感動する

少しずつ学んでいくうちに、なぜそのFWがどんな思想に基づいて作られているのか
というところまで辿り着きます。
postd.cc

例えばRails(Ruby)の基本理念の
プログラマの幸福度を最適化する」
そんなことを考えて世界がソースコードを作るなんて
文化ってすごすぎませんか、アガペーすら感じます

未経験での学習と実務は全然違う

数ヶ月学習した内容は実務の1〜2週間で終わりました。。。

1日12時間集中して1週間連続で勉強できる、
そして先輩に聞けるという環境は驚くほど好環境です。
あれほど進まなかった、わからなかったものがどんどん進むと
数ヶ月に渡って実施してきたことが1、2週間で
あれ?こんなのに迷ってたの?というレベルになります。

コードの書き方が全く違う

当たり前ですが実務→保守が発生します。
保守性の高いコードを、規約に則ったコードを、
などルールや制限が増え、ベストプラクティスを考えるようになります。
これがまた難しくて面白いのです。

業務に関わるインプットは増える、それ以外のインプットは増えない

例えば私の場合、Laravelについて、PHPについてのインプットはかなり増えました。
当然ですが、業務で一切触れないものについては自分で収集するほかありません。
逆に言えば、業務で触れられる技術が古ければ、
新しいものは自分でキャッチアップするほかない。想像以上でした!

集中力が50分に1回くらい切れる

これは衝撃です。1時間に1回くらい、ばちん、と切れるのです。
(人により差があると思いますが)
切れるのは仕方ないとして、集中力を戻す時に時間がかかる、
いい方法あったら教えてください。

そのほか

・めっちゃお腹すく
・会話が減る(笑)
・運動が減る
・そして当然のごとく太る

ああ、だからエンジニアは筋トレをするのか、が最近の結論です。
個人的マイブームは腹筋です。


2017年が終わる前に、まとめておきたかったのでまとめました。
まだ2ヶ月しか経っていないので、また1年たったあたりで記事書きたいなと思います。
今は本当に、とにかくエンジニアになってよかったです。幸せです。
エンジニアになりたい人は、是非、チャレンジしてみてください。

最後に、自分がエンジニアになるにあたり関わってくださった皆様に
心の底から感謝申し上げます。

【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