2020.05.25
# Web制作
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,
]);
}
}








