2020.05.25
docker + laravelで作る超簡易フォーム
今回は勉強会で使ったネタです。
docker + laravelで作る超簡易フォーム
を作ってみました。
少々説明が必要な部分もありますが、基本的にはコピペで進めるようになっています。(※動かない部分があるかもしれない・・・)
今回は入力画面、完了画面からなるシンプルなお問合せフォームでメール送信のみを行います。
HTMLは味気ないですが、ご容赦ください・・・。
では、早速いってみましょう!
前提条件
勉強会で行った際に確認をしたOSは下記です。
MacOS 10.15(Catalina)
Windows 10pro
dockerを事前に登録&インストールする必要があります。
※無料です
こちらで、アカウントを作成し、自身のOSにあったdockerをインストールしましょう。
※Windows10 Homeではそのままインストールできないため、茨の道をいくことになるかもしれません。(非推奨)
まずはDockerで環境構築
docker-compose.ymlを作成します
version: '3' services: php: container_name: php build: ./docker/php volumes: - .:/var/www depends_on: - db nginx: image: nginx container_name: nginx ports: - 8011:80 volumes: - .:/var/www - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: XXXXXXXX ports: - '8001:3306' volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:
続いて、下記のディレクトリとファイルを作成しましょう。
docker/nginx/default.conf
docker/php/Dockerfile
docker/php/php.ini
それぞれのファイルは下記のようにします。
docker/nginx/default.conf
server{ listen 80; index index.php index.html; root /var/www/public; location / { try_files $uri $uri/ /index.php$is_args$args; index index.html index.php; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }
docker/php/Dockerfile
FROM php:7.2-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql exif #GDのインストール RUN apt-get install -y wget libjpeg-dev libfreetype6-dev RUN apt-get install -y libmagick++-dev \ libmagickwand-dev \ libpq-dev \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libwebp-dev \ libxpm-dev RUN docker-php-ext-configure gd RUN docker-php-ext-install -j$(nproc) gd #Composer install COPY --from=composer /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www #RUN composer global require "laravel/installer"
docker/php/php.ini
[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"
dockerを起動する
つづいて下記のコマンドを打っていきます。
docker-compose up ☆テスト用DBを作る docker-compose exec db bash mysql -u root -p XXXXXXXX create database test; ☆laravel インストール docker-compose exec php bash composer global require laravel/installer laravel new .
インストールができたら.envファイルを設定します
.env.exampleを.envにリネーム
※このとき.envはgitなどの対象としないようにしましょう!
下記の設定を行う。
#下記はSMTPアカウントを所持していればそれを使いましょう。 MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null #ここまで MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}" DB_CONNECTION=mysql #※今回DBは使いません #ここがdbになるのが肝 DB_HOST=db DB_PORT=3306 #testは create database test; で作ったものです。 DB_DATABASE=test #DBのusernameはrootにし、DB_PASSWORDはdocker-compose.ymlで指定したものを使います。 DB_USERNAME=root DB_PASSWORD=XXXXXXXX
routesの設定
routes/web.phpに追加する
Route::get('contact', 'ContactController@index')->name('contact.index'); Route::post('contact/complete', 'ContactController@complete') ->name('contact.complete');
1番目の引数がマッチするURLです。
完了画面はRoute::getではなく、Route::postとなっていることに注目!
Controllerファイルの作成
app/Http/Contollers/ContactController.phpを作成します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class ContactController extends Controller { public function index() { //フォーム入力ページのviewを表示 return view('contact.index'); } public function complete(Request $request) { $this->validate($request, [ 'contact_type'=> 'required|string|max:191', 'name' => 'required|string|max:191', 'tel' => array('required','string','max:191','regex:/^([0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}|[0-9]{5,12})$/'), 'email' => 'required|email|string|email|max:191', 'message' => 'string|max:400', ] ); // 二重送信防止のためトークンを発行 $request->session()->regenerateToken(); \Mail::send(new \App\Mail\ContactMail([ 'email' => $request->email, //フォームに入力したメールアドレス 'name' => $request->name, //フォームに入力した名前 'from' => env('MAIL_FROM_ADDRESS'), 'from_name' => env('MAIL_FROM_NAME'), 'subject' => 'お問い合わせ受付完了のお知らせ', //メールの件名 'contact_type' => $request->contact_type, //お問い合わせの種類 'tel' => $request->tel, //お電話番号 'message' => $request->message, //ご利用目的 ])); //to.blade.phpに反映する //完了ページのviewを表示 return view('contact.complete'); } }
Viewの作成を行います
resources/views/layouts/common.blade.php
レイアウトの親ファイルです。
<!doctype html> <html> <head> <title>タイトル</title> <meta charset="UTF-8"> <meta name="format-detection" content="telephone=no"> </head> <body> @yield('content') @yield('scripts') </body> </html>
resources/views/contact/index.blade.php
入力画面です。
@extends('layouts.common') @section('content') {{-- エラーメッセージ --}} @if (count($errors) > 0) <ul class="alert alert-danger" role="alert"> @foreach ($errors->all() as $error) <li class="ml-4">{{ $error }}</li> @endforeach </ul> @endif {{-- 本体 --}} <div id="form" data-target="form"> <div id="contact_form01"> {{ Form::open(['route' => 'contact.complete']) }} <table border="1" class="list_03 books_table01"> <tbody> <tr> <td>お問い合わせの種類</td> <td> {{Form::select('contact_type', [ '' => 'お問い合わせの種類をご選択ください', '出版物の入手方法' => '出版物の入手方法', 'その他' => 'その他'] )}} </td> </tr> <tr> <td>ご氏名</td> <td>{!! Form::text('name', null, ['class' => 'form_control']) !!}</td> </tr> <tr> <td>お電話番号</td> <td>{!! Form::tel('tel', null, ['class' => 'form_control']) !!} </td> </tr> <tr> <td>メールアドレス</td> <td>{!! Form::email('email', null, ['class' => 'form_control']) !!} </td> </tr> <tr> <td>本文</td> <td>{!! Form::textarea('message', null, ['class' => 'form_control', 'rows' => '6']) !!} </td> </tr> </tbody> </table> <div class="form_submit_btn">{!! Form::submit('送信', ['class' => 'btn']) !!}</div> </div> {{ Form::close() }} </div> @endsection @section('scripts') @endsection
resources/views/contact/complete.blade.php
完了画面です。
@extends('layouts.common') @section('content') <p>送信が完了しました</p> @endsection @section('scripts') @endsection
Formクラスがつかえるようにする
きっと、「Class ‘Form’ not found」なんて出るので、下記のコマンドを打ち込む
composer require laravelcollective/html
する。
ここまでで、入力画面が表示されているはずです。
http://localhost:8011/contact
にアクセスしてみましょう!
※8011は「docker-compose.yml」で設定したporstの値です。
翻訳ファイルの修正
エラーが英語でしたよね?
resources/lang/ja/validation.phpを作成して、対訳を行います。
https://readouble.com/laravel/5.6/ja/validation-php.html
こあたりをありがたく使わせていただきます。
config/app.php
localeをja(日本語)にしましょう。
'locale' => 'ja',
このままだと中途半端に日本語になっているため、「resources/lang/ja/validation.php」ファイルをさらに調整します。
'attributes' => [ 'contact_type'=>'お問合せの種類', 'name'=>'名前', 'tel'=>'電話番号', 'email'=>'メールアドレス', 'message'=>'本文', ],
こうすることで、name値も日本語に置き換わります。
メール送信用のViewを作成
{{ $content['name'] }} 様<br> <br> この度はお問い合わせいただき誠にありがとうございます。<br> お客様からのお問い合わせを受付けましたので、ご連絡いたします。<br> <br> ============================<br> <br> お問い合わせ種別:{{ $content['contact_type'] }}<br> 氏名{{ $content['name'] }}<br> 電話番号:{{ $content['tel'] }}<br> メールアドレス:{{ $content['email'] }} <br> 本文:{!! nl2br($content['message']) !!}<br> <br> ============================<br> <br> 内容を確認のうえ、担当よりご回答いたします。<br> <br>
最後にメール送信用のクラスを作成します
app/Mail/ContactMail.phpファイルを作成しましょう。
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class ContactMail extends Mailable { use Queueable, SerializesModels; protected $content; protected $viewStr; /** * Create a new message instance. * * @return void */ public function __construct($content) { $this->content = $content; } /** * Build the message. * * @return $this */ public function build() { return $this->view('contact.emails.to') ->to($this->content['email'], $this->content['name']) ->from($this->content['from'], $this->content['from_name']) ->subject($this->content['subject']) ->with([ 'content' => $this->content, ]); } }