20200922のlaravelに関する記事は9件です。

【ローカル環境】Laravelアプリ作ってローカルDB(MAMP)にテーブル作るまで

Laravelでいろいろなハンズオン形式の練習をしていくにあたり、
アプリ作成からテーブル作成まで、毎回ちょっと調べるのが面倒になってきたのでまとめます。

前提環境/どんな方向け?

・mac OS 10.15(10.14や10.13でも大きな違いはなし)
・MAMPをmacにインストール済みであること。
・ターミナル操作がわからないこともないこと。
・Laravelはmacにインストール済みであること。
・composerも入れていること。

という感じで、しょっぱなからの説明ではなく、過去にlaravelをmampで構築されており、ローカル環境で新しくアプリを作る方向け(主に自分の備忘録)です。

手順

1.Laravelアプリを作る

まずはアプリ作成。「todoLife」というアプリを作る場合は下記の手順。
ターミナルで、

composer create-project "laravel/laravel=5.8.*" todoLife

※バージョン指定は任意です。不要な場合は「laravel/laravel」でokです。
ここでは5.8の中の最新版を指定してみます。

また、このコマンドを行うことで、「今いる場所」にフォルダ/プロジェクトを作ります。
例えばデスクトップに「todoLife」というフォルダを作り、その中にcdで移動して上記のコマンドを実行すると
desuktop/todoLife/todoLife (← laravelのアプリ)
という感じになっちゃいます。
ので、desktopに作りたい場合はデスクトップに移動して実行しましょう。
(この後すぐmamp内に移動しますが)

2.MAMP内に移動

作ったララベルプロジェクトをmampの中のhtdocsに移動しましょう。
具体的には下記のような配置となります。

Macintosh ハードディスク/Applications/MAMP/htdocs/プロジェクタフォルダ

phpデータをローカルのmampで表示、動作させるにはこの「htdocs」の中に保管している必要があります。

3.DBを作る

MAMPで予めDBを作っておきます。
開発環境ではあるので大体でもいいかもですが、アプリ名と同じにしているケースが多いです。

MAMPの中でnewから作成しましょう。
※照合順序は「utf8_general_ci」でokです。
01.png

4.テーブルを作る

手動でMAMP内で作ってもいいですが、ここではlarabelのマイグレーション機能で作ってみます。今回作るのはシンプルに「todo」のテーブル「todos」です。

※なお、laravelのプロジェクト > database > migrations の中にデフォルトで存在している

2014_10_12_000000_create_users_table.php
2014_10_12_100000_create_password_resets_table.php

は、ユーザーテーブルやパスワードリセットが不要ならば削除しても問題ないです。

マイグレーションとは?

マイグレーションを行うことにより、このmigrationsファイルの中の「up()」の処理を実施します。
この後マイグレーションファイルの中身を見ますが、これらのファイルのupでは、テーブルを作るという処理が書かれています。
そのため、デフォルトの状態でマイグレーションをすると、前述の既存の二つのファイルにより、「ユーザーテーブル」と、「パスワードリセットのテーブル」が作られる、ということになります。

今回はそのままにしておき、マイグレーションファイルを別途作ります。
作る方法は、ターミナルでプロジェクトフォルダのトップにいるときに

php artisan make:migration create_todos_table --create=todos

と実施します。
ここで中盤と最後にある「todos」が、作成するファイル名、テーブル名になります。
テーブル名は通常複数形として作成する必要があります。postなら「posts」などです。

次にmigrationsの中にできた記述を見てみましょう。こんな関数ができているはずです。

2020_xx_xx_123630_create_todos_table.php
class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('todos');
    }
}


up()が、migration実行時に作られるテーブルの情報、そして
down()がやっぱその処理をやめるときに巻き戻す(ロールバック時に)実行される処理です。

今回、各todosには題名と本文をつけたいので、こんな感じでtitle、bodyテーブルを作る記述を追加します。

    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title',50);//追加
            $table->text('body');//追加
            $table->timestamps();
        });
    }

それでは、下記の手順でマイグレートを実行します。

php artisan migrate

む。エラーとなりました。
スクリーンショット 2020-09-22 22.03.30.png

5.環境設定

DBとの接続設定をまだ行っていませんでした。
その辺の環境設定は.envファイルで行います。
.envはプロジェクトのトップディレクトリ直下に存在しています。
02.png
いじるのはこの辺。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todoLife //アプリ名に変更
DB_USERNAME=root
DB_PASSWORD=root //パスワードを設定。mamp側でDBにログインするためのユーザーごとのid、パスワードを設定します。


config/app.php
config/database.php
というファイルも編集します!

//app.php
//タイムゾーンと言語設定を変更しておきましょう。
    'timezone' => 'Asia/Tokyo',
    'locale' => 'ja',
//database.php
//database名、ユーザーネーム、パスワード、unix_socketを修正します。

'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'todoLife'),//修正
            'username' => env('DB_USERNAME', 'root'),//修正
            'password' => env('DB_PASSWORD', 'root'),//修正
            'unix_socket' => env('DB_UNIX_SOCKET', '/Applications/MAMP/tmp/mysql/mysql.sock'),//修正


6.もう一度マイグレーション

今度は成功しました!
03.png

mampを見てもちゃんとtodos、users、passwordresetテーブルがつくられています。
スクリーンショット 2020-09-22 22.23.54.png

終わり!

おまけ

マイグレーションしてなくても見れますが、プロジェクトフォルダでphp artisan serveして、
mampを起動しておけばlaravelの起動も確認できます!
スクリーンショット 2020-09-22 22.25.51.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel7フォームでお問い合わせが送信されたらサイト運営者にメールで知らせる

やりたいこと

要件

  • コンタクトフォームから名前、メアド、メッセージを記入して送信すると、その内容がサイト運営者にメールが飛ぶ。
  • アカウント登録がなくてもゲストでも送信できる。
  • DBは使用しない。
  • Heroku、ローカル開発環境(MAMP)両方で機能する。

初めてなので、まずはシンプルなものを実装。今後、入力確認画面とかエラーメッセージとか色々応用出来たらいいなと思っています。

やるべきことを俯瞰します

  • Mailtrapの準備
  • Laravelアプリ内のメールの環境設定
  • ビューの作成(xxx.blade.php)
  • コントローラの設定(XxxController.php)
  • ルートの設定(web.php)
  • Mailableの準備(XxxXxx.php)
  • メールのテンプレート作成(xxx.blade.php)

やってみた

Mailtrapの準備

Mailtrapとは、Webアプリで使用するメールを助けてくれるサービスです。
https://mailtrap.io/ でサインアップ(GitHub連携などで一瞬で登録出来ます)。

Laravelアプリ内のメールの環境設定

Mailtrapを開いて、Inboxes→歯車マーク→SMTP Settingsタブへ。
スクリーンショット 2020-09-22 14.04.49.png
Integrationsという箇所を見つけたら、ドロップダウンリストからLaravelを選択。その下に表示されるCredentialsのSMTPのUsernameとPasswordを控えます。
ローカル開発環境から設定します。.envファイルを開き、下記のように修正。(隠れファイルなのでご注意。隠しファイルを表示するにはMacならCommand + Shift + .同時押し)

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=Mailtrapを見てここ修正
MAIL_PASSWORD=Mailtrapを見てここ修正
MAIL_ENCRYPTION=Mailtrapを見てここ修正
MAIL_FROM_ADDRESS=お好みで修正
MAIL_FROM_NAME="${APP_NAME}" ここも適宜修正

次にHeroku用の環境。上記設定だけでは、Herokuでは機能しません。それもそのはず。私の場合、.envファイルを.gitignoreファイルに入れてgitの管理対象外にしているからです。
なので、Herokuの環境設定をすればOKです。方法は2つあって、コマンドラインを使う方法とHerokuサイト上でGUIで入力する方法です。HerokuサイトならSettingsタブを開いて、Config VarsでReveal Config Varを押すと入力欄が出てきます。

コマンドラインなら下記のようなコマンドを。ちなみに私は、Laravelアプリのディレクトリにいる状態で行いました。.envファイルで行った設定をそのまんまHerokuにも設定してあげればよいですね。

$ heroku config:set MAIL_HOST=smtp.mailtrap.io
$ heroku config:set MAIL_USERNAME=Mailtrapを見てここ修正
$ heroku config:set MAIL_PASSWORD=Mailtrapを見てここ修正
$ heroku config:set MAIL_ENCRYPTION=Mailtrapを見てここ修正
$ heroku config:set MAIL_FROM_ADDRESS=お好みで修正

余談で、下のようにconfig/mail.appファイルを編集するというやり方もありますが、機密情報がダダ漏れしてしまうのでやめた方が良さそうです。

mail.app
   'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.mailtrap.io'), //ここをMailtrapに変更
            'port' => env('MAIL_PORT', 587),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => 'Mailtrapを見てここ修正', //ここ修正
            'password' => 'Mailtrapを見てここ修正', //ここ修正
            'timeout' => null,
            'auth_mode' => null,
        ],

ビューの作成(xxx.blade.php)

resources/views/contact/contact.blade.phpという形で作成しました。フォームの作成例です。必要最小限の表記にしています。

contact.blade.php
<form action="process" method="post">
  @csrf
  <div>
    <label for="name">お名前</label>
    <input type="text" name="name" id="name">
  </div>
  <div>
    <label for="email">メールアドレス</label>
    <input type="email" name="email" id="email">
  </div>
  <div>
    <label for="message">お問い合わせの内容</label>
    <textarea name="text" cols="40" rows="8" id="message"></textarea>
  </div>
  <div>
    <input type="submit" value="送信する">
  </div>
</form>

ポイント

  • @csfr:Laravelで必須のCSRF対策。(Cross Site Request Forgeryの略)
  • formタグのaction属性:フォーム送信後のアドレスになる
  • formタグのmethod属性:post。HTTPのPOSTメソッドに相当。フォームのデータをサーバーに送信する。
  • inputやtextareaタグのname属性:入力値の値はこのnameと一緒にサーバーに送信される重要な属性。

コントローラの設定(XxxxController.php)

コマンドラインで、ファイルを作成します。あるサイトでは、Laravel規約では複数形でないといけないと書いてましたが、某教科書は単数形なので教科書に倣います。

$ php artisan make:controller ContactController

下記のように編集していきます。

ContactController.php
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;//追記
use App\Mail\ContactMail; //追記。後に作るMailable。後述。

class ContactController extends Controller
{
    //contact.blade.php表示
    public function index()
    {
        return view('contact.contact'); //'contactフォルダの中のcontace.blade.php'
    }
    //メール送信
    public function process(Request $request)
    {
        $request->validate([ //バリデーション
            'name'     => 'required',
            'email'    => 'required|email',
            'text'     => 'required',
        ]);
        $input = $request->all();
        unset($input['_token']); //CSRF非表示フィールド_token削除
        Mail::to('送信先メアド')->send(new ContactMail('contact.mail', 'お問い合わせを受信しました', $input));
        return redirect('/');
    }
}

ルートの設定(web.php)

web.php
//Contactページの表示
Route::get('contact', 'ContactController@index');

//フォームの受け取りとメール送信
Route::post('process', 'ContactController@process'); //先のformタグのaction属性はこの第一パラメータと関係する

Mailableクラスの準備

Mailableとは、Laravelアプリが送信するメールを操作するクラスです。詳しくは公式ドキュメントを。今回はContactMail.phpという名前で作成しました。

php artisan make:mail ContactMail

app/MailディレクトリにContactMail.phpが生成されました。

ContactMail.php
<?php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    public $data; //追記
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($template, $subject, $data)
    {
        $this->subject = $subject; //件名
        $this->data = $data; //フォームで受信したデータ
    }

    /**
     * Build the message.送信するメールの設定はbuildメソッド
     * 
     * @return $this
     */
    public function build()
    {
        return $this->from('メールの発信先アドレス')//fromメソッドでメールの送信メアドを設定。
                    ->view('contact.mail');//メールのテンプレートを指定。ここではcontactフォルダのmail.blade.phpを指定。
    }
}

メールのテンプレート作成(xxx.blade.php)

views/contact/mail.blade.php
<head>
  <style>
    h1 {
      font-size: 18px;
    }
    p {
      font-size: 14px;
    }
  </style>
</head>
<body>
  <h1>{{$data["name"]}}様からの、お問い合わせを受信しました。</h1>

  <p>メールアドレス: {{$data["email"]}}</p>
  <p>内容:  {{$data["text"]}}</p>
</body>

ポイントは、Mailableクラスから受け取ったデータを{{$data[""]}}でフォームデータを表示できるという点でしょう。

最後に

これでうまく設定できていれば、フォームで送信すると、Mailtrapの受信箱でメールを受信することができます。
スクリーンショット 2020-09-22 20.59.17.png

何かご指摘、アドバイスあればよろしくお願い申し上げます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker x Laravel phpMyAdmin を導入する

以前の記事(最強のLaravel開発環境をDockerを使って構築する【新編集版】)のコメントにてphpMyAdminを使用したいという要望がありましたので補足の記事を作成させていただきます。

手順

https://github.com/ucan-lab/docker-laravel

docker-compose.yml に phpMyAdmin のサービスを追加

docker-compose.yml
volumes:
  # 追記
  pma-session-store:

services:
  # 追記
  pma:
    image: phpmyadmin/phpmyadmin:5.0.2
    environment:
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=secret
    ports:
      - 8080:80
    volumes:
      - pma-session-store:/sessions

Dockerコンテナの構築

$ docker-compose up -d

phpMyAdmin へアクセス

http://127.0.0.1:8080

上記のURLへアクセスし、phpMyAdminの画面が表示されればokです。

ScreenShot 2020-09-22 19.11.42.png

ScreenShot 2020-09-22 19.11.46.png

補足

MySQL新認証プラグイン caching_sha2_password

私のdbコンテナの設定でMySQL8.0系で認証方式を新しいcaching_sha2_passwordに設定しています。phpMyAdminは5.0.1以降でないとcaching_sha2_passwordに対応していないのでタグで新しいバージョンを明示的に指定してます。latestが5系を指すようになったら外してもいいかもです。

蛇足

(MySQLのCLIやSequel Ace等のクライアントツールで特に不便がないのでがあるので個人的にはphpMyAdminは入れなくてもいいかなと思ってます)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker x Laravel phpMyAdmin のコンテナを構築する

以前の記事(最強のLaravel開発環境をDockerを使って構築する【新編集版】)のコメントにてphpMyAdminを使用したいという要望がありましたので補足の記事を作成させていただきます。

手順

https://github.com/ucan-lab/docker-laravel

docker-compose.yml に phpMyAdmin のサービスを追加

docker-compose.yml
volumes:
  # 追記
  pma-session-store:

services:
  # 追記
  pma:
    image: phpmyadmin/phpmyadmin:5.0.2
    environment:
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=secret
    ports:
      - 8080:80
    volumes:
      - pma-session-store:/sessions

Dockerコンテナの構築

$ docker-compose up -d

phpMyAdmin へアクセス

http://127.0.0.1:8080

上記のURLへアクセスし、phpMyAdminの画面が表示されればokです。

ScreenShot 2020-09-22 19.11.42.png

ScreenShot 2020-09-22 19.11.46.png

補足

MySQL新認証プラグイン caching_sha2_password

私のdbコンテナの設定でMySQL8.0系で認証方式を新しいcaching_sha2_passwordに設定しています。phpMyAdminは5.0.1以降でないとcaching_sha2_passwordに対応していないのでタグで新しいバージョンを明示的に指定してます。latestが5系を指すようになったら外してもいいかもです。

蛇足

(MySQLのCLIやSequel Ace等のクライアントツールで特に不便がないのでがあるので個人的にはphpMyAdminは入れなくてもいいかなと思ってます)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

入力欄が別の時の期間カスタムバリデーションLaravel5.5

入力欄が別の期間のバリデーションをかけようと思うと
2015-3~2017-4ではバリデーションがうまくかかるが、
2018-8~2018-6だとエラーを吐かなかったので
バリデーションをかける前に連結させました。
誰かの参考になればと思い、残しておきます

laravel5.5でFormRequestを使う場合コントローラの処理を実行する前にバリデーションがかかってしまうので、
先に文字列を連結させる必要がありました。
なので文字列を連結させてそれをフォームから送信させているようにしてバリデーションをかけるようにしました。

もちろん入力欄を分けなければafterafter_or_equalbeforebefore_or_equalなどを使えばいいのですが。。
送信前にリクエストを加工するには6.xではprepareForValidation()メソッドを使えばいいみたいなので参考にはならないと思います

まずはこれを追加してください

use Illuminate\Validation\Validator;

その後にメインロジックを追加していきます
見ての通り、連結させて$requestに追加しています
それに伴って

    protected function validationData()
    {
        $this->addStartOfRegisterDate();
        $this->addEndOfRegisterDate();
        $this->addStartOfEnrollmentDate();
        $this->addEndOfEnrollmentDate();
        return parent::validationData();
    }

    private function addStartOfRegisterDate()
    {
        $start_of_register_year = (string)$this->request->get('start_period_of_register_year');
        if ($start_of_register_year === '') return;
        $start_of_register_month = (string)$this->request->get('start_period_of_register_month');
        if ($start_of_register_month === '') return;
        $start_of_register_date = $start_of_register_year . '-' . $start_of_register_month;
        $this->request->add(['start_of_register_date' => $start_of_register_date]);
    }

    private function addEndOfRegisterDate()
    {
        $end_of_register_year = (string)$this->request->get('end_period_of_register_year');
        if ($end_of_register_year == '') return;
        $end_of_register_month = (string)$this->request->get('end_period_of_register_month');
        if ($end_of_register_month == '') return;
        $end_of_register_date = $end_of_register_year . '-' . $end_of_register_month;
        $this->request->add(['end_of_register_date' => $end_of_register_date]);
    }

    private function addStartOfEnrollmentDate()
    {
        $start_of_enrollment_year = (string)$this->request->get('start_period_of_enrollment_year');
        if ($start_of_enrollment_year === '') return;
        $start_of_enrollment_month = (string)$this->request->get('start_period_of_enrollment_month');
        if ($start_of_enrollment_month === '') return;
        $start_of_enrollment_date = $start_of_enrollment_year . '-' . $start_of_enrollment_month;
        $this->request->add(['start_of_enrollment_date' => $start_of_enrollment_date]);
    }

    private function addEndOfEnrollmentDate()
    {
        $end_of_enrollment_year = (string)$this->request->get('end_period_of_enrollment_year');
        if ($end_of_enrollment_year == '') return;
        $end_of_enrollment_month = (string)$this->request->get('end_period_of_enrollment_month');
        if ($end_of_enrollment_month == '') return;
        $end_of_enrollment_date = $end_of_enrollment_year . '-' . $end_of_enrollment_month;
        $this->request->add(['end_of_enrollment_date' => $end_of_enrollment_date]);
    }

これによって連結された文字列が$requestに入るので、そこにバリデーションをかけるようにしましょう

'start_of_register_date' => 'nullable|before_or_equal:end_of_register_date',
'end_of_register_date' => 'nullable|after_or_equal:start_of_register_date',
'start_of_enrollment_date' => 'nullable|before_or_equal:end_of_enrollment_date',
'end_of_enrollment_date' => 'nullable|after_or_equal:start_of_enrollment_date',

これをrules()returnに追加しましょう

全体を見るとこんな感じですー

MypageUpdateRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class MypageUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'birth_year' => 'nullable|integer|min:' . config('common.validate_min.birth_year') . '|max:' . config('common.validate_max.birth_year'),
            'birth_month' => 'nullable|integer|min:' . config('common.validate_min.birth_month') . '|max:' . config('common.validate_max.birth_month'),
            'birth_day' => 'nullable|integer|min:' . config('common.validate_min.birth_day') . '|max:' . config('common.validate_max.birth_day'),

            'start_period_of_register_year' => 'nullable|string|required_with:company_name,start_period_of_register_month,end_period_of_register_month|integer|min:1969|max:date(Y)',
            'start_period_of_register_month' => 'nullable|string|required_with:company_name,start_period_of_register_year,end_period_of_register_year|integer|min:1|max:12',
            'start_of_register_date' => 'nullable|before_or_equal:end_of_register_date',
            'end_period_of_register_year' => 'nullable|string|required_with:company_name,start_period_of_register_month,end_period_of_register_month|integer|min:1969|max:date(Y)',
            'end_period_of_register_month' => 'nullable|string|required_with:company_name,end_period_of_register_year,start_period_of_register_year|integer|min:1|max:12',
            'end_of_register_date' => 'nullable|after_or_equal:start_of_register_date',
            'start_period_of_enrollment_year' => 'nullable|string|required_with:school_name,start_period_of_enrollment_month,end_period_of_enrollment_month|integer|min:1969|max:date(Y)',
            'start_period_of_enrollment_month' => 'nullable|string|required_with:school_name,start_period_of_enrollment_year,end_period_of_enrollment_year|integer|min:1|max:12',
            'start_of_enrollment_date' => 'nullable|before_or_equal:end_of_enrollment_date',
            'end_period_of_enrollment_year' => 'nullable|string|required_with:school_name,start_period_of_enrollment_month,end_period_of_enrollment_month|integer|min:1969|max:date(Y)',
            'end_period_of_enrollment_month' => 'nullable|string|required_with:school_name,start_period_of_enrollment_year,end_period_of_enrollment_year|integer|min:1|max:12',
            'end_of_enrollment_date' => 'nullable|after_or_equal:start_of_enrollment_date',
        ];
    }

    protected function validationData()
    {
        $this->addStartOfRegisterDate();
        $this->addEndOfRegisterDate();
        $this->addStartOfEnrollmentDate();
        $this->addEndOfEnrollmentDate();
        return parent::validationData();
    }

    private function addStartOfRegisterDate()
    {
        $start_of_register_year = (string)$this->request->get('start_period_of_register_year');
        if ($start_of_register_year === '') return;
        $start_of_register_month = (string)$this->request->get('start_period_of_register_month');
        if ($start_of_register_month === '') return;
        $start_of_register_date = $start_of_register_year . '-' . $start_of_register_month;
        $this->request->add(['start_of_register_date' => $start_of_register_date]);
    }

    private function addEndOfRegisterDate()
    {
        $end_of_register_year = (string)$this->request->get('end_period_of_register_year');
        if ($end_of_register_year == '') return;
        $end_of_register_month = (string)$this->request->get('end_period_of_register_month');
        if ($end_of_register_month == '') return;
        $end_of_register_date = $end_of_register_year . '-' . $end_of_register_month;
        $this->request->add(['end_of_register_date' => $end_of_register_date]);
    }

    private function addStartOfEnrollmentDate()
    {
        $start_of_enrollment_year = (string)$this->request->get('start_period_of_enrollment_year');
        if ($start_of_enrollment_year === '') return;
        $start_of_enrollment_month = (string)$this->request->get('start_period_of_enrollment_month');
        if ($start_of_enrollment_month === '') return;
        $start_of_enrollment_date = $start_of_enrollment_year . '-' . $start_of_enrollment_month;
        $this->request->add(['start_of_enrollment_date' => $start_of_enrollment_date]);
    }

    private function addEndOfEnrollmentDate()
    {
        $end_of_enrollment_year = (string)$this->request->get('end_period_of_enrollment_year');
        if ($end_of_enrollment_year == '') return;
        $end_of_enrollment_month = (string)$this->request->get('end_period_of_enrollment_month');
        if ($end_of_enrollment_month == '') return;
        $end_of_enrollment_date = $end_of_enrollment_year . '-' . $end_of_enrollment_month;
        $this->request->add(['end_of_enrollment_date' => $end_of_enrollment_date]);
    }

    public function messages()
    {
        return [
            'birth_year.integer' => '正しい年を選択してください',
            'birth_year.max' => '正しい年を選択してください',
            'birth_year.min' => '正しい年を選択してください',
            'birth_year.required_with' => '月と日も選択してください',
            'birth_month.integer' => '正しい月を選択してください',
            'birth_month.max' => '正しい月を選択してください',
            'birth_month.min' => '正しい月を選択してください',
            'birth_month.required_with' => '年と日も選択してください',
            'birth_day.integer' => '正しい日を選択してください',
            'birth_day.max' => '正しい日を選択してください',
            'birth_day.min' => '正しい日を選択してください',
            'birth_day.required_with' => '月と日も選択してください',

            'start_period_of_register_year.integer' => '在籍期間を正しく選択してください',
            'start_period_of_register_year.max' => '在籍期間を正しく選択してください',
            'start_period_of_register_year.min' => '在籍期間を正しく選択してください',
            'start_period_of_register_year.required_with' => '年も選択してください',
            'start_period_of_register_month.integer' => '在籍期間を正しく選択してください',
            'start_period_of_register_month.max' => '在籍期間を正しく選択してください',
            'start_period_of_register_month.min' => '在籍期間を正しく選択してください',
            'start_period_of_register_month.required_with' => '月も選択してください',
            'start_of_register_date.before_or_equal' => '在籍開始期間を正しく選択してください',
            'end_period_of_register_year.integer' => '在籍期間を正しく選択してください',
            'end_period_of_register_year.max' => '在籍期間を正しく選択してください',
            'end_period_of_register_year.min' => '在籍期間を正しく選択してください',
            'end_period_of_register_year.required_with' => '年も選択してください',
            'end_period_of_register_month.integer' => '在籍期間を正しく選択してください',
            'end_period_of_register_month.max' => '在籍期間を正しく選択してください',
            'end_period_of_register_month.min' => '在籍期間を正しく選択してください',
            'end_period_of_register_month.required_with' => '月も選択してください',
            'end_of_register_date.after_or_equal' => '在籍終了期間を正しく選択してください',
            'start_period_of_enrollment_year.integer' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_year.max' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_year.min' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_year.required_with' => '年も選択してください',
            'start_period_of_enrollment_month.integer' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_month.max' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_month.min' => '在籍期間を正しく選択してください',
            'start_period_of_enrollment_month.required_with' => '月も選択してください',
            'start_of_enrollment_date.before_or_equal' => '在籍開始期間を正しく選択してください',
            'end_period_of_enrollment_year.integer' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_year.max' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_year.min' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_year.required_with' => '年も選択してください',
            'end_period_of_enrollment_month.integer' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_month.max' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_month.min' => '在籍期間を正しく選択してください',
            'end_period_of_enrollment_month.required_with' => '月も選択してください',
            'end_of_enrollment_date.after_or_equal' => '在籍終了期間を正しく選択してください',

        ];
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel8以降でルーティングがうまくいかない件

Laravel8.Xからrouteの記述方法が変わって面倒になったかもしれません。(自分でも検証済み)
Laravel7.X以前→Laravel8.X以降はエラーになったと思ったが、解決した件。

route/web.php

Route::get('/', 'TestController@index');

laravel8.X以降はこのようにしないとうまく行かなかった。。
route/web.php

use App\Http\Controllers\TestController;
Route::get('/',[TestController::class, 'index']);

しかし、Laravel8でも、app/Providers/RouteServiceProvider.php の bootメソッドでnamespaceを指定すればこれまで通りの動作をすることがわかった。
(土日にも関わらず、疑問に対応いただいた私の上司に感謝。。)

app/Providers/RouteServiceProvider.php

public function boot()
    {
        $this->configureRateLimiting();
        $this->routes(function () {
            Route::middleware('web')
                ->namespace('App\Http\Controllers')   ← 【これを足す】
                ->group(base_path('routes/web.php'));
            Route::prefix('api')
                ->middleware('api')
                ->group(base_path('routes/api.php'));
        });
    }

これで今まで通り(Laravel7以前のようにルーティングがうまくいく)
routes/web.php

Route::get('/test', 'TestController@index');

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(メモ) Laravel 8入門

コマンドの作成

コマンドの作成
php artisan make:command SampleCommand
  • Kernel.phpに登録
app/Console/Kernel.php
    protected $commands = [
+       Commands\SampleCommand::class
    ];
登録されているか確認
php artisan list | grep "command:name"
編集
    public function handle()
    {
+       echo "hi ";
        return 0;
    }
実行
php artisan command:name

引数

  • {変数名} を追加すると、引数がなければエラーになる。
app/Console/Commands/SampleCommand.php
-   protected $signature = 'command:name';

    # 引数は必ず必要
+   protected $signature = 'command:name {arg1}';

    # 引数がなくても良くする。
+   protected $signature = 'command:name {arg1?}';

    # 引数がない場合の初期値
+   protected $signature = 'command:name {arg1=user1}';

    # 引数の説明
+   protected $signature = 'command:name {name=laravel : 名前を指定} {age? : 年齢を指定}';
# エラーになる
php artisan command:name

# エラーにならなくなる。
php artisan command:name aa
  • コマンドライン引数の取得
app/Console/Commands/SampleCommand.php
    public function handle()
    {
        echo "hi ";
+       $arg1 = $this->argument("arg1");
+       echo $arg1;
        return 0;
    }

オプションの指定

# オプションの指定
protected $signature = 'command:name {--dry-run}';

# 実行
php artisan command:name --dry-run

## オプション取得
$dry_run = $this->option("dry-run"); // true or false
# オプションの値を取得方法
protected $signature = 'command:name {--greeting=}';

# 実行
php artisan command:name --greeting=Hello

## オプションの値を取得
$greeting = $this->option("greeting"); // Hello
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでapi.phpに送れない

何をしているか

https://www.hypertextcandy.com/vue-laravel-tutorial-authentication-part-4/
上記サイトを参考にLaravel × Vue のアプリ開発の勉強をしています

ただ、Laravelの更新により、現在のバージョンではコピペでエラーが出てしまうことがありました。

躓いた箇所

上記サイトのところで、api.phpにgetを渡したのにも関わらず、web.phpの
Route::get('/{any?}', fn() => view('index'))->where('any', '.+');
が参照されてしまいました。

解決策

app\Providers\RouteServiceProvider.php の箇所で

public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('web')
                ->group(base_path('routes/web.php'));

            Route::prefix('api')
                ->middleware('web')
                ->group(base_path('routes/api.php'));
        });
    }

となっている箇所を

public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('web')
                ->group(base_path('routes/api.php'));
            Route::middleware('web')
                ->group(base_path('routes/web.php'));
        });
    }

に変更しました。
要するにwebとapi の読み込む順番を逆にするということです。

同じところで躓いた人は試してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel_CRUD処理を使った投稿アプリを作成する その10 バリデーションエラーを日本語に変える

目的

  • アプリを作成する上で基本となるCRUD処理を有したLaravelアプリをチュートリアル的に作成する方法をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

前提情報

  • ソースコードはこちら→https://github.com/miriwo0104/laravel_crud/tree/master
  • DockerやAWSなどは使用せずにMacのローカルに実施環境と同じLaravel開発環境を構築して実施する。
  • チュートリアルで実際に筆者が作成したソースコードをGitHubにて公開予定である。
  • CRUD処理の作成完了を最短目標にしてバリデーションなどは後々設定することとする。
  • 実施環境と同じ環境がDockerやAWSで用意できるなら都度読み替えていただければ実施が可能だと思う。
  • 公式ドキュメントと一冊の技術書を元に本記事を記載する。
  • DBへの意図しないデータの流入を防ぐためバリデーションを実装する。
  • 問い合わせの内容は「入力がされていること」のバリデーションルールを、新規投稿と投稿編集は「入力されており、かつ140文字以内であること」定義してバリデートする。
  • バリデーションで弾かれた時に出力されるエラーメッセージを自分好みの物に変える方法を記載する
  • バリデーションルールは下記の公式ドキュメントに数多く記載されているので実装できたら遊んでみるのもいいかもしれない。

この記事の読後感

  • バリデーションエラーをユーザ任意の物に変更することができる。

概要

  1. Requestファイルの修正
  2. 確認

詳細

  1. Requestファイルの修正

    1. laravel_crudディレクトリで下記コマンドを実行してリクエストファイルを開く。

      $ vi app/Http/Requests/ContentRequest.php
      
    2. 開いたコントローラファイルを下記のように修正する。

      laravel_crud/app/Http/Requests/ContentRequest.php
      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Foundation\Http\FormRequest;
      
      class ContentRequest extends FormRequest
      {
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          public function rules()
          {
              return [
                  'content' => ['required', 'max: 140'],
              ];
          }
      
          // 下記を追記する
          public function messages()
          {
              return [
                  'content.required' => '内容を記入してください。',
                  'content.max' => '投稿内容は140文字以下にしてください。',
              ];
          }
          // 上記までを追記する
      }
      
    3. laravel_crudディレクトリで下記コマンドを実行してリクエストファイルを開く。

      $ vi app/Http/Requests/InquiryRequest.php
      
    4. 開いたコントローラファイルを下記のように修正する。

      laravel_crud/app/Http/Requests/InquiryRequest.php
      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Foundation\Http\FormRequest;
      
      class InquiryRequest extends FormRequest
      {
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          public function rules()
          {
              return [
                  'content' => ['required'],
                  'name' => ['required'],
              ];
          }
      
          // 下記を追記する
          public function messages()
          {
              return [
                  'content.required' => '内容を記入してください。',
                  'name.required' => '内容を記入してください。',
              ];
          }
          // 上記までを追記する
      }
      
  2. 確認

    1. laravel_crudディレクトリで下記コマンドを実行しローカルサーバを起動する。

      $ php artisan serve
      
    2. 下記にユーザ認証後、下記にアクセスする。

    3. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_input.png

    4. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    5. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_edit_5.png

    6. 下記にユーザ認証後、下記にアクセスする。(コンテンツのidは1以外でも構わない)

    7. 何も入力せず「送信」をクリックし下記のようにエラーが出ることを確認する。

      127_0_0_1_8000_inquiry_input.png

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む