[PHP]Laravelを使ったメールフォームの作り方

Laravel 5.6 を使い、お問い合わせ用のコンタクトフォームを作っていきます。
古いバージョンでも概ね同じですが、Bootstrap 4 が使われていることに注意して下さい。

まず最初にメールに関する初期設定を行っておきます。設定箇所は .env ファイルの「MAIL_」から始まる項目です。お使いのアカウントに合わせて各項目を書き換えて下さい。
MAIL_ENCRYPTION には tls, ssl, null のいずれかが設定できます。

次の2行がない場合は .env に書き足すか、 config/mail.php の from の項目を編集して下さい。

MAIL_FROM_ADDRESS=送信元のメールアドレス
MAIL_FROM_NAME=送信者の名前

次に routes/web.php でルーティングを用意します。

Route::get('/contact', 'ContactController@form')->name('contact');
Route::post('/contact', 'ContactController@send')->name('contact.send');
Route::get('/contact/result', 'ContactController@result')->name('contact.result');

それぞれフォーム画面、送信処理、送信結果の3つです。

artisan のコマンドを使ってコントローラーを作成します。

php artisan make:controller ContactController

app\Http\Controller に ContactController.php が作られます。
まずはフォーム画面となる form() メソッドを追加します。

    public function form()
    {
        return view('contact.form');
    }

ひとまず最低限ビューが表示できるようにしたので Blade テンプレートファイルを用意します。場所は resources/views です。contact フォルダを新しく作り、その中に form.blade.php ファイルを作成します。
すでに layouts/app.blade.php などの親テンプレートが存在する場合はそのまま使っていきますが、ない場合は作成します。

layouts/app.blade.php

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        @yield('content')
    </div>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

contact/form.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="card">
        <div class="card-body">
            <form method="POST" action="{{ route('contact.send') }}">
                {{ csrf_field() }}

                <div class="form-group">
                    <label for="formInputName">Name</label>
                    <input type="text" class="form-control" id="formInputName" name="name" value="{{ old('name') }}">

                    @if ($errors->has('name'))
                        <span class="help-block">
                            <strong>{{ $errors->first('name') }}</strong>
                        </span>
                    @endif
                </div>

                <div class="form-group">
                    <label for="formInputEmail">Email address</label>
                    <input type="text" class="form-control" id="formInputEmail" name="email" value="{{ old('email') }}">

                    @if ($errors->has('email'))
                        <span class="help-block">
                            <strong>{{ $errors->first('email') }}</strong>
                        </span>
                    @endif
                </div>

                <div class="form-group">
                    <label for="formInputEmail">Message</label>
                    <textarea class="form-control" id="formInputMessage" name="message" value="{{ old('message') }}">{{ old('message') }}</textarea>

                    @if ($errors->has('message'))
                        <span class="help-block">
                            <strong>{{ $errors->first('message') }}</strong>
                        </span>
                    @endif
                </div>

                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
    </div>
</div>
@endsection

Laravel ではメールの送信を Mailable クラスを通して行っています。メールの種類ごとに次のコマンドでメールを処理するためのクラスを作ります。「Contact」の部分は好きな名前にして下さい。(例: OrderShipped)

php artisan make:mail Contact

これで app\Mail フォルダに Contact.php が作られます。
入力内容に合わせて文面を表示するために、引数として受け取れるようにしていきます。

class Contact extends Mailable
{
    use Queueable, SerializesModels;

    public $data = [];

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data['inputs'] = $data;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.contact')->with($this->data);
    }
}

プロパティ $data を追加し、コンストラクタで inputs に代入します。(inputs の名前は何でも構いません) 代入したデータは build() の with() でビューに渡しています。
連想配列 inputs に入れずに直接代入するのが一般的ですが、Mailable では $message という変数は他のデータが入っていて使えないため、上書きされるのを防ぐためにこのような形をとっています。

そして build() で指定したメールの文面となるビューファイルを用意します。view() を使ったときは html メールになります。プレーンテキストで送りたい場合は代わりに text() を使って下さい。

emails/contact.blade.php

<p>Name: {{ $inputs['name'] }}</p>
<p>Email: {{ $inputs['email'] }}</p>
<p>{!! nl2br( $inputs['message'] ) !!}</p>

次は ContactController に戻り、冒頭に use を書き足します。

use App\Mail\Contact;
use Illuminate\Support\Facades\Mail;

そして送信処理 send() を実装します。

    public function send(Request $request)
    {
        $rules = [
            'name' => 'required|string',
            'email' => 'required|email',
            'message' => 'required'
        ];
        $this->validate($request, $rules);

        $to = [
            ['email' => 'example@gmail.com', 'name' => 'Your Name']
        ];

        $data = $request->only('name', 'email', 'message');
        Mail::to($to)->send(new Contact($data));

        return redirect()->route('contact.result');
    }

送信時にバリデーションを行って入力欄に空欄がないか、メールアドレスは正しいかをチェックしています。 入力内容に問題がなければ送信処理を行います。$to には送信先を指定します。複数指定することができます。 名前が必要ない場合は null にしておきます。

今回作った Contact クラスの引数として入力内容を渡し、send() で送信です。

送信が終わったら redirect() で完了ページに移動します。送信完了ページはテンプレートを表示するだけです。

    public function result()
    {
        return view('contact.result');
    }

contact/result.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="card">
        <div class="card-body">
            <h3>Thanks.</h3>
            <p>Your email has been successfully sent.</p>
        </div>
    </div>
</div>
@endsection

try catch や Mail::failures() を使ってエラー時の処理を追加するのも良いと思いますが、基本的には 送信時のエラーしか拾えません。送信には成功したものの実際には受信側の容量が不足していて受け取れなかったなどのケースもありえますので注意して下さい。

[PHP]2018年現在使っているおすすめの開発ツール・開発環境(Mac)

PHPでの開発を始めた頃と現在では随分使っているツールや開発環境が変わってきました。
そこで現在主に使用しているものを紹介してみます。

開発機

MacBook Pro (15-inch, Early 2011)

ものすごく古いマシンなのは承知していますが簡単にメモリやストレージを増設できるので重宝しています。メモリを 16GB に増設し、ハードディスクを SSD に換装したのでまだ使えますが、グラフィックメモリが 256MB しか無いので時間の問題です。もう少し新しいモデルも持っているのですがメモリが増設できないため(8GBでは足りませんでした)そちらは使っていません。

IDE, テキストエディタ

PhpStorm

もはや説明不要ですが JetBrains の PHP 専用 IDE です。これの代わりになるものは無いと思います。
最新バージョンの PHP や各種フレームワークへの対応も早いので安心感があります。

Visual Studio Code

Microsoft がオープンソースで開発しているテキストエディタです。
一時期 Atom を中心に使っていましたが現在は完全にこちらです。
プラグインがひと通り出揃ったので構文エラーのチェックや定義への移動など本格的な事もできます。

ローカルサーバー, データベース

Vagrant

Cent OS 7 を Virtual Box で利用しています。最初の構築が大変ですが自由度が高いので好きなようにカスタマイズできます。サーバー自体の勉強にもなるので触れておいて損はないと思います。
今は使い慣れた Apache で動かしていますがいずれは nginx も覚えないといけないなと考えています。

Valet

Laravel が作ったローカル開発環境です。MAMP に近いものではありますが、ホスト名とフォルダの割当てが簡単にできるのでかなり楽です。詳細なサーバー設定が必要ないのであればこれで十分です。

その他開発ツール

SourceTree

GitHub や BitBucket のリボジトリを管理する定番のツールです。
ターミナルで十分な時もありますがブランチの状況やコンフリクトの確認がしやすいので持っていると心強いです。

Postman

POST, GET などのリクエストをテストするためのツールです。Ajax 処理や API 開発の際にあると便利です。

Sequel Pro

GUI でデータベースを操作するためのツールです。ちょっとした修正や正しくテーブルが作られているかの確認に使ったりします。

ForkLift

2ペインに分割できる Finder のようなアプリケーションです。不可視ファイルの表示/非表示が簡単にできるので見やすいです。一応ファイル一括リネームや FTP 用のツールにもなります。

グラフィック

Photoshop

なんだかんだで手放せないツールです。Affinity Photo なども試しはしたものの他の方とデータをやり取りするのに不便なので変えられません。
主な用途はバナー作成や写真の加工です。以前は装飾されたボタンや文字を作るのに使うことが多かったですが最近はシンプルなデザインがほとんどなので立体的な文字や透明感のあるボタンなどは需要が減ってきました。

Illustrator

ロゴやアイコンを作るのに使用しています。JavaScript で自動処理ができるので各アイコンを一気に SVG として書き出すなどの処理が簡単にできます。最近ではウェブでもベクター画像を取り扱うことが珍しくなくなったので使う機会は多いです。

Sketch

ウェブデザインを組み上げるには Sketch を使っています。Photoshop で加工した画像や Illustrator で作ったロゴなどを配置してレイアウトを作ります。
ヘッダーやメニュー等のパーツの使いまわしや修正に強いのが便利です。最近はページをリンクさせて遷移のプレビューができるといったプロトタイピングツールとしての機能も追加されたのでサイトの雰囲気を確認するのにも役立っています。

PHPエンジニアから見た他のプログラミング言語

いろいろなプログラミング言語を少し知っていると専門外のソースコードからでも知識が得られます。また、普段使っているものがどれだけ奇異なものなのかわかったりもするので常識的なプログラミングをする上でも重要な事だと思います。

そこで普段 PHP を中心に使っている自分から見た他の言語の印象と特徴を書いてみます。
偏見だらけで間違った内容も含まれます。あまり真剣に捉えないでくださるとありがたいです。

Python

Python でもウェブプログラミングはできますが、人工知能やディープラーニングなどの機械学習分野での活躍のほうが目立っています。インデントに意味を持たせた書き方は独特で驚きましたが可読性が高く合理的です。学術系のライブラリが充実しているのも特徴で、この分野においては他の言語よりも圧倒的に生産効率が高いです。
Django フレームワークを使ったウェブサイト制作や、3DCGのスクリプトなどいろいろな分野をカバーしています。
個人的には FontForge でウェブフォントを作るのに使ったりします。
国内での情報は Ruby に比べるとやや少ないものの海外ではかなりメジャーな言語です。

Ruby

ウェブに関わる者にとって Ruby の存在感は大きいです。なかでも Ruby on Rails は PHP 製フレームワークに強く影響を与えた存在でもあるので構造には見慣れた感じがあります。ウェブサービスの分野では主要な言語なのでいつかマスターしてみたいと思う気持ちは強いです。
小規模なレンタルサーバーなどでは動作する環境が揃っていない事が多く、AWS などのクラウドサービスや VPS などの自由度の高いサーバーで使う機会がほとんどなので環境構築自体が難しく、気楽に始められるものではない印象です。
ウェブに強い言語ではありますがその他の分野でも利用でき、Vagrant などのソフトウェアの開発言語としても知られています。
いくつかフレームワークはあるものの Ruby on Rails がほぼ一強なので「Ruby ができる = Ruby on Rails ができる」と言えるため、フレームワーク選定に迷わなくて済むのはちょっと羨ましいです。

PHP

HTML内にプログラムを埋め込めるため簡易テンプレートとして使われることが多かった PHP ですが、最近ではクラスの実装や大型フレームワークの登場、PHP 7.0 での高速化によってちゃんとしたウェブプログラミングができるように成長しました。
文字列や配列はメソッドを持たないため、「$foo->count()」のようにする代わりに「count($foo)」とするなど関数が中心となっています。
クラスの作成がサポートされるようになってからも標準関数中心の時代からの影響を引きずっています。
代表的なブログアプリケーションである WordPress は大きなシェアを持っており、使うぶんには優れていますが、古い設計と新しい設計が混在するソース構造はひどい状態で、常用されるグローバル変数とクラスにまとめられていない変数群が多用されており、良いお手本とはいえません。
人気のあるフレームワークの Laravel は PHP の良い面を活かした柔軟なフレームワークで中規模サイトでの活躍も増えてきました。

Perl

一昔前までは CGI といえば Perl で、掲示板やチャットはこれで作るものという状況がありましたが今ではすっかり影が薄くなって元気がない印象です。
この頃は CGI は自分で作るものというよりも大御所の配布サイトから頂いて設置したり、レンタルするものと言う感覚がありました。ある意味では国内でウェブプログラミングが停滞した理由はこのあたりにあるのかもしれません。
いつの間にか Perl で作られたブログは WordPress に取って代わり、個人サイトに掲示板を設置する文化自体なくなってしまいました。

Java

Windows, Mac, Linux など OS を選ばずに動作するのが特徴で、GUI ライブラリも用意されているので見た目や操作感も統一できます。Android プログラミングの主要言語なのでかなりのプログラマーが習得している言語の1つです。
他の言語に与えた影響も大きく、Java を知っておくといろいろな言語のソースコードが何となく読めるようになります。何かのアルゴリズムについて知りたいときはたいてい Java のソースがネット上にあるので PHP に置き換えて使ったりしています。
ちょっとしたデスクトップ GUI ツールが必要で Windows や Mac で使う時に Java で組むことが多いです。以前は GUI の見た目が OS ネイティブからかけ離れた不格好なものだったのであまりおしゃれな印象がなかったのですが最近は随分きれいな見た目になりました。
デメリットとして Java がインストールされていなくては動作せず、Java のバージョンにも大きく左右されるため、ユーザー側にもある程度コンピュータの知識を要求してしまいます。

JavaScript

上述の Java と名前が似ているだけでなんの関係もないというのは有名な話です。
以前はウェブページの文字をちょっと動かしたりマウスカーソルにキラキラするものをつけたりする程度のものでしたがjQuery の登場とブラウザでの実行速度があがってから一気に人気が爆発しました。
ウェブアプリでもほぼ必須の存在で、多くのシングルページアプリケーションが作られています。
Node.js の登場によりサーバーサイドでも動作するようになってから更に人気が加速し、Electron を使ったデスクトップアプリも最近ではよく見かけられるようになりました。OS を選ばずに動作するという意味では Java に近いものがあり、HTML + CSS の知識があれば簡単に見た目が作れるためデスクトップアプリの分野でも急速に利用者が増えています。
ES2015(ES6)で正式なクラス構文やモジュール構文を始めとした重要な機能追加があったのですが互換性確保のため Babel, TypeScript, CoffeeScript などのトランスパイラを利用するのが事実上必須になるなどまだちょっとふわふわと落ち着かない感じがあります。

C#

基本的には Windows での GUI プログラムを作成するための言語ですが最近では他の OS でも使えるように努力が続けられています。
Java と似たところのある書き方で直感的に作れるのが魅力で、アプリケーションの実行には .NET Framework が必要なものの Windows には標準付属のため事実上のネイティブアプリを作ることができます。
優れた IDE である Visual Studio で利用でき、C言語や C++ よりも最初の一歩を踏み出すハードは低いです。
人気のゲームエンジン Unity でも C# が使えることも高い人気の理由です。

Visual Basic

C# が今ほどメジャーになる前は Visual Basic はよく使われていました。学習用言語 BASIC を大幅に拡張したもので、業務用のアプリケーション開発で人気がありました。
C# 同様に Visual Studio で GUI の作成ができ、プログラミング初心者に限らず多くのアプリケーションが作られていました。
Microsoft Excel などで簡易版の VBA が利用できるため、事務書類作成の効率化の分野で重宝されています。

Swift

非常に癖があり難解だった Objective-C に替わるものとして作られた言語で、iOS アプリや Mac 用のデスクトップアプリケーション開発用に使われています。
型や nil の扱いに厳しく、暗黙的な型変換が行われないためいい加減な作り方をすることが許されません。ある意味では安定したソフトウェアを作るよう強制されているともいえます。
現時点では限られた用途にしか使えませんが Swift はオープンソース化されているので将来的には Android や Windows などの OS でも動かせるようになるかもしれません。


以上が主要なプログラミング言語の紹介でした。
言語自体の優劣よりもライブラリの人気が言語の人気に大きく関わっています。
普段使っている言語がこの先も使われ続ける保証はないので特定の言語に依存せず時代の流れについて行けるかが重要になってくると思います。