20200712のlaravelに関する記事は12件です。

【PHP】フレームワーク「Laravel」での開発環境構築(Mac版)

はじめに

今回、フレームワーク「Laravel」を用いてのアプリ開発を行うことになりました。

前提として、私は「Laravel」を使用することが初めてのため、今回記載する内容より最適な手順は他にもあるかもしれません。

ただ、「まずは何から始めれば、、」という初学者の方には得るものがあるかもしれないので、参考にしていただければ幸いです。

開発環境

・MacOS:10.14.6

目標

PHP7.3、Laravel6をインストール

概要(簡単な流れとコマンド)

①Homebrewのインストール

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

②PHPのインストール

brew install php@7.3

③Composerのインストール

$ brew install composer

④Laravelのインストール

$ composer create-project "laravel/laravel=6.*" プロジェクト名

⑤確認

$ php artisan serve

http://localhost:8000/

手順

②PHPのインストール

$ brew search php
==> Formulae
brew-php-switcher                 php-code-sniffer                  php@7.2                           phplint                           phpmyadmin                        phpunit
php                               php-cs-fixer                      php@7.3                           phpmd                             phpstan
==> Casks
homebrew/cask/eclipse-php 
$ brew install php@7.3
Updating Homebrew...

~ 省略 ~
$ php -v 
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
$ echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
$ php -v
PHP 7.3.20 (cli) (built: Jul  9 2020 23:55:30) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.20, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.20, Copyright (c) 1999-2018, by Zend Technologies

③Composerのインストール

$ brew search composer
==> Formulae
composer
$ brew install composer
Updating Homebrew...
==> Downloading https://getcomposer.org/download/1.10.8/composer.phar
######################################################################## 100.0%
?  /usr/local/Cellar/composer/1.10.8: 3 files, 1.9MB, built in 3 seconds
$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.10.8 2020-06-24 21:23:30

~ 省略 ~

④Laravelのインストール

ここではバージョン指定をしたLaravelのインストールと同時に「phpsample」というプロジェクト名でディレクトリを作成します。

$ composer create-project "laravel/laravel=6.*" phpsample
Creating a "laravel/laravel=6.*" project at "./phpsample"
Installing laravel/laravel (v6.18.8)
  - Installing laravel/laravel (v6.18.8): Downloading (100%)
$ cd phpsample
$ php artisan serve

⑤確認

http://localhost:8000/

参考文献

本記事を作成するにあたり、以下を参照させていただきました。
ありがとうございます。

https://qiita.com/1992_momotaro/items/c84ad1701c4623c04f27
https://qiita.com/YutakaYamasaki/items/96ab3f20a71d6c825b5d
https://deha.co.jp/magazine/laravel-php-mvc/

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

【Laravel】ファビコン(WEBブラウザタブのアイコン)を簡単に作成・設定する方法

使用するサイト

Favicon & App Icon Generator

image.png

使用するのはこちらのサイト。
どんなサイズでもいいので画像を用意しておけば、それをファビコン用に加工・生成してくれます。

Favicon & App Icon Generator

ファビコンの作り方

ファビコンにしたい画像を用意して、Favicon & App Icon Generatorにアクセス
ファイルをアップロードする。
image.png

切り替わった後の画面で、ファビコン化した画像をDLする
image.png

この画面のHTMLタグは後で使います。

ファビコンを設定する

アプリ内にファビコンを配置

welcome.blade.phpがレイアウト構成を担うbladeファイル
という設定で配置します。

①resourcesディレクトリに画像を保存するimageディレクトリを作成
②さらにimageの中にfaviconディレクトリを作成
faviconの中に先ほどDLしたファビコン画像を移動

レイアウト構成を担うbladeファイルで参照する

welcome.blade.php

タグに、先ほどのファビコンDLページのHTMLタグをコピペします。
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
        <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
        <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
        <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
        <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
        <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
        <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
        <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
        <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
        <link rel="icon" type="image/png" sizes="192x192"  href="/android-icon-192x192.png">
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
        <link rel="manifest" href="/manifest.json">
        <meta name="msapplication-TileColor" content="#ffffff">
        <meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
        <meta name="theme-color" content="#ffffff">

href(参照パス)を修正する

hrefのhref(パス)はwelcome.blade.phpからの相対パスになります。
よって、コピペしたhrefを全て下記のように修正しましょう。

href="../images/favicon/apple-icon-57x57.png"

これで設定は完了!
レイアウトで使っているbladeページを表示すればファビコンが設定されているのが分かります。

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

短縮URLサービスがどんどん終了しているので、自分でOSSライブラリ「URL Shorter」開発してみた

はじめに

昨今、「短縮URL」サービスがどんどん終了しています。
私が一番使っていたサービスはGoogleの短縮URLだったのですが、いつまにか終了してしまっていました。

短縮URLサービスはめちゃくちゃ便利なんですが、いかんせん不正や詐欺に使われてしまうというデメリットがあります。
上記で書いた残り1つについても、いつ終わってしまうか分かりません。

そこで、「それならば自分用の短縮URLサービスを作ろう!」と思い立ち、開発し始めました。
かつ、どうせ作るなら、自分だけのものではなく、OSSライブラリとして開発することに決めました。
Laravel製なので、いま開発されているLaravelソリューションがあれば、そのパッケージに組み込むことで、短縮URL生成をかんたんに利用することが可能です。
GitHubにて、MITライセンスで公開済みです。
https://github.com/hirossyi73/url-shorter

せっかくの機会ですし、Qiitaでもご紹介することにしました。

短縮URL一例

機能

短縮URL生成機能

URLを入力すると、短縮URLを生成してくれます。

screen1.gif

文字列の長さと、使用する文字は、設定ファイルで変更することが出来ます。
文字列が長ければ長いほど、重複は発生しにくいですが、文字列は短い方が短縮URLとしてはカッコいいです。
その辺はお好みで。

短縮URL生成ページの認証機能

Googleをはじめとした、各種短縮URLサービスが終了した原因の99.9999999%は、間違いなく、詐欺サイトや犯罪などに使われる「不正利用」だと思っています。

screen3.gif

なので、今回開発したライブラリでは、短縮URL生成ページにパスワード認証を付けることができます。
パスワードを知らない人は短縮URLを生成出来ないので、不正利用に使われる可能性はグッと減るはずです。

プレビュー機能

短縮URLをブラウザで入力した際に、直接リダイレクトせず、プレビュー画面を表示することができます。
「本当にこのサイトにアクセスしますか?」的な機能ですね。

screen2.gif

APIから短縮URL作成、URL復元

このライブラリでは、短縮URL作成とURL復元を、APIから呼び出すことができます。
なので、他のシステムから、「短縮URLを生成する」的なこともしやすいです。

ちなみに、API機能やパスワード認証機能は、設定によりオンオフが可能です。
用途によって、必要な場合のみオンにする・・・ということができるので、柔軟性は高いです。

Laravelから短縮URL作成、復元

もちろん、プログラムから直接短縮URLを生成することも可能です。
いま開発されているLaravelソリューションがあれば、そのパッケージに組み込むことで、短縮URL生成をかんたんに利用することが可能です。

use Hirossyi73\UrlShorter\Model\Shorter;

// 短縮URL生成
$shorter = Shorter::create([
    'url' => $url
]);
return $shorter->generate_url;

// 短縮URLからURL復元
$shorter = Shorter::findByGenerateUrl($generate_url);
return $shorter->url;

ライブラリ・ライセンス情報

Laravelフレームワークとして開発しています。PHP7.0.0以上、Laravel5.5以上。
ちなみに、最新(2020/07/12現在)のLaravel7での動作も確認しています。

ライセンスはMITです。
https://github.com/hirossyi73/url-shorter

その他

このライブラリですが、短縮URL生成ページを公開する予定はありません。
前述してますが、先行サービスが相次いで終了したのは、間違いなく不正利用です。公開するとなると、それらの不正利用の対処も必要になってきます。

なのでこのライブラリは、
・自分だけが短縮URL生成を行えるような設定で利用する
・社内で短縮URL生成など、限られた環境で利用する
・短縮URL生成のエンドポイントは公開せず、短縮URL生成はプログラムのみに絞る
このような用途が良いんじゃないか、と思っています。

ちなみにこのライブラリは、だいたい10時間ぐらいで開発・公開しました。
もともと開発しているOSSのWebデータベース Exment のソースコードを流用しているものもありますが、それにしても超速で開発できるのは、Laravelは本当に素晴らしいですね。

良ければ、URL Shorter、ご利用ください!

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

Laravelでキューを使う

キュー

実行したい処理(ジョブ)をjobsテーブル(キュー)に入れて置き、後で実行するものです

前提条件

eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

Laravelでデータベースを扱う準備をする
Laravelでテーブル作成
Laravelで初期データ投入
本記事は上記の内容を理解している前提で書かれています
本記事は上記ので作成したデータベースとレコードを使用します

jobsテーブル生成

コマンドラインで
sample
php artisan queue:table
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/database/migrations/xxxx_xx_xx_xxxxxx_create_jobs_table.phpが現れます

マイグレーション実行

コマンドラインで
sample
php artisan migrate
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します

jobsテーブルができました

データベースを使うように設定

/sample/.env修正

‥‥
QUEUE_CONNECTION=database
‥‥

QUEUE_CONNECTIONをdatabaseにします
この値は
/sample/config/queue.phpで使われます

ジョブ生成

(1) コマンドラインで
sample
php artisan make:job SampleJob
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Jobs/SampleJob.phpが現れます

(2) SampleJob.php修正

SampleJob.php
<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SampleJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $sample;

    public function __construct($sample)
    {
        $this->sample = $sample;
    }

    public function handle()
    {
        error_log("SampleJob " . $this->sample . PHP_EOL, 3, __DIR__ . DIRECTORY_SEPARATOR  . "SampleJob.log");
    }
}

コンストラクタとメソッドを修正しました
handleメソッドはジョブが処理されるときに呼びだされます
error_log関数でSampleJob.phpと同階層のSampleJob.logというファイルに文字列を出力するようにしています

Controllerにメソッド追加

(1) /sample/app/Http/Controllers/SampleController.phpにuse文を追記
use App\Jobs\SampleJob;

(2) /sample/app/Http/Controllers/SampleController.phpにjobメソッドを追記

SampleController.php
    public function job()
    {
        SampleJob::dispatch("afterResponse")->afterResponse();
        SampleJob::dispatch("delay 3 Seconds")->delay(now()->addSeconds(3));

        return view('sample.job');
    }

SampleJob::dispatchの引数に渡しているものはSampleJobクラスのコンストラクタの引数になります。
afterResponseはブラウザにレスポンスを送り終えたらジョブを実行するものです
delayは指定した引数時間後にジョブを実行します。delayの引数に渡しているnow()はLaravelが提供しているヘルパ関数でCarbonクラス(https://carbon.nesbot.com/)を返します。今回はaddSeconds(3)で3秒後にジョブが実行されるようにしています。addSecondsの他にもいろいろ関数があります(carbon Docs Addition and Subtraction)
SampleJob::dispatch("delay 3 Seconds")->delay(now()->addSeconds(3));で先ほど作成したjobsテーブルにジョブがinsertされます

(3) /sample/routes/web.phpに下記を追記
Route::get('sample/job', 'SampleController@job');

viewの作成

/sample/resources/views/sample/job.blade.phpファイル作成

job.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        job
    </body>
</html>

キューワーカーの起動

キューワーカーとは、キュー(jobsテーブル)に投入されたジョブを処理してくれるものです
sample
php artisan queue:work
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
これは常時実行させておくものです。本番ではSupervisor等で常時動くように設定してください(http://supervisord.org/)(Laravel 7.x キュー Supervisor設定)
また、ジョブを修正した場合はキューワーカーを再起動してください
キューワーカーの再起動コマンドです
php artisan queue:restart
(Laravel 7.x キュー キューワーカーのデプロイ)

動作確認

http://localhost/laravelSample/sample/job

MySQLでlaravel_sampleデータベースを確認してみましょう
select * from jobs;
3秒後に実行されるジョブが入っています
ジョブが実行されるとレコードはdeleteされます
/sample/app/Jobs/SampleJob.logが作成され、afterResponseもdelay 3 Secondsも出力されています

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

laravel 認証機能のリダイレクト先変更

laravelの初期設定では、ログインやユーザ登録後のリダイレクト先は/homeとなっています。
これを変更するには、下記のコントローラーの記述を修正する必要があります。

・修正するコントローラー
RouteServiceProvider.php

・場所
プロジェクト名
-app
-Providers
-RouteServiceProvider.php

・修正する場所
24行目
public const HOME = '/home';

public const HOME = '/';

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

【Laravel】バリデーションの作成

バリデーションを簡単に安全にかけるための方法メモ。

フォームリクエスト

バリデーション専用のフォルダを作って処理をさせる。
書きコマンドを打ってrequestフォルダとファイルを作成。

php artisan make:request StoreContactForm

ファイル名は任意。

Controller

controller内にフォルダとファイルが出来てるはずなので確認。

Controller/Requests/StoreContactForm.php
public function authorize()
    {
        return true;  //falseからtrueに変更
    }
.
.
.

public function rules()
    {
        return [
            //ここにバリデーションのルールを書く
            'name' => 'required|string|max:20',
            'title' => 'required|string|max:50',
            'email' => 'required|email|unique:users|max:255',
            'gender' => 'required',
            'contact' => 'required|accepted',
        ];
    }

ルールは公式参照。
https://readouble.com/laravel/7.x/ja/validation.html#rule-url】

作成したデータを送る際に表示させたいので、storeメソッドに適応してあげる。

ContactFormController.php
//バリデーションのファイルを呼び出し
use App\Service\CheckFormData;

//第一引数をRequestからバリデーションクラス名にする
public function store(StoreContactForm $request)
    {
        $contact = new ContactForm;
        $contact->name = $request->input('name');
        $contact->email = $request->input('email');
        $contact->title = $request->input('title');
        $contact->gender = $request->input('gender');
        $contact->contact = $request->input('contact');

        $contact->save();

        return redirect('contacts/index');
    }

View

エラーメッセージを表示します。

create.blade.php
@if($errors->any())
    <ul>
        @foreach($errors->all() as $error)
            <li class="list-group-item list-group-item-danger">{{$error}}</li>                    @endforeach
    </ul>
@endif

$errorsはViewファイルに与えられてる変数らしいです。
こいつを回してあげて該当するもののみ表示します。

まとめ

バリデーションは最初ややこしい印象があるのですが、大事な部分でもあるので徐々に慣れていきたいです。

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

Laravel6 認証機能 Authのセットアップ

Laravel6以降では、Auth機能を利用するために下記の二つをまず準備する必要があります

・laravel/ui
・Node.js(npm使用のため)

1 Node.jsのインストール

下記のサイトからインストールを実施
https://nodejs.org/ja/

2 laravel/uiのインストール

composer require laravel/ui

※コマンド実行場所は、laravelプロジェクトのディレクトリで。
デスクトップ上で、laravelappというプロジェクトを作成している場合
C:\Users\PC_User\Desktop\laravelapp>composer require laravel/ui

3 Auth機能関連のファイルを作成

php artisan ui vue --auth

上記のコマンドを実行すると、web.phpに
Auth::routes();
という、認証機能に必要なルーティングが自動で追加されたりする。
※laravel/uiがないと失敗するので、先にインストールは済ませておく

vendor
-laravel
上記のフォルダに uiフォルダ が作成されており、
RegisterUsers.phpとかはこの中に格納されている。

4 最後に

npm install && npm run dev

を実行して完了。
windows10だと、完了時にPC画面の左下になんか表示が出ます。
※少し時間がかかります。

5 確認してみよう

実際にログイン画面と登録画面にアクセスして確認してみましょう。
・登録画面
url
~/register

・ログイン画面
url
~/login

※localhostなら、localhost:8080/registerとか

認証機能のviewは、viewsフォルダのauthフォルダに生成されます。

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

Windows環境でhomesteadを利用してLaravel開発環境構築時のNET::ERR_CERT_AUTHORITY_INVALID

久しぶりにWindows環境でhomesteadを利用してLaravel開発環境を構築した際のChromeでの初期動作確認時に、上記エラーが発生して時間を無駄にしてしまったので、備忘録として残しておきます。

環境

以下の環境で構築しました。

  • Windows 10
  • VirtualBox 6.0.22
  • Homestead 10.9.1
  • Vagrant 2.2.9
  • Laravel Framework 7.19.1

エラーの内容

エラー内容.png
LaravelのWebサイトで紹介されているLaravelのインストールマニュアル及び、Homesteadのインストール手順に沿って環境の構築を進めたのち、サイトの初期動作確認時に上記メッセージが表示され、動作確認ができませんでした。

原因

Homestead.yamlファイルのsites設定で、sample.devというドメインを使用したことが原因でした。

Homestead.yaml
sites:
    - map: sample.dev
      to: /home/vagrant/code/sample/public

理由としては、Chrome & Firefox now force .dev domains to HTTPS via preloaded HSTSに記載がありました。

簡単に記載すると、.devで終わるすべてのドメインは強制的にHTTPSにリダイレクトするようになっているためです。

対策

もっとも簡単な対策としては、.devで終わるドメインを使わないことです。

以上です。
開発環境を作る際に無駄な時間を浪費しないよう、気を付けたいと思います。

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

【Laravel】リクエスト・レスポンスを補完する

書籍のアウトプットとして

前回はミドルウェアの登録までやったので今回はグローバルミドルウェアをやっていく

グローバルミドルウェア

前回は一つのミドルウェアに一つのアクセスで登録したがすべてのアクセスでミドルウェアを実行できるのはグローバルミドルウェア

グローバルミドルウェアの登録

Kernel.phpの配列へ追記をして登録する

Http/Kernel.php
    protected $middleware = [
   ...
    ];

グローバルミドルウェアを登録すると個々のミドルウェアの呼び出しは必要無くなる。

web.php
Route::get('hello', 'HelloController@index')->middleware(HelloMiddleware::class);

これがこうなる

web.php
Route::get('hello', 'HelloController@index');

ミドルウェアグループ登録

グループ化して登録する仕組み。
Kernel.phpの$middleGroupsという変数に設定されている。

Kernel.php
    protected $middlewareGroups = [
        'web' => [
        ..ミドルウェアクラス...
        ],

        'api' => [
        ..ミドルウェアクラス...
        ],
    ];

'web''api'という項目がグループ

グループを利用する

グループに登録する際は、$middlewareに登録していたものを削除する必要がある。

配列に追加する。

Kernel.php
'hello'=>[\App\Http\Middleware\HelloMiddleware::class,],

web.phpを修正

web.php
Route::get('hello', 'HelloController@index')->middleware('hello');

グループの場合はmiddlewareの引数へグループ名をテキスト値で渡す。

バリデーション

フォームなどでの値の検証をバリテーショという

バリデーションとは

Larabelではvalidateメソッドを利用できる。
これはコントローラの基底クラスに組み込まれている。
ValidateRequestというトレイトの機能。

アクションメソッドからの呼び出しはこう

$this.->validate($request,[検証設定の配列]);
引数 説明
第1引数 リクエスト
第2引数 検証する設定情報の配列

配列はこんな感じ

[
  '項目名'=>'割り当てる検証ルール',
  '項目名'=>'割り当てる検証ルール',
   ....
]

バリデーションの利用

inndex.blade.php
@section('content')

<p>{{$msg}}</p>
<form action="/hello" method="post">
  <table>
    @csrf
    <tr><th>name:</th><td><input type="text" name="name"></td></tr>
    <tr><th>mail:</th><td><input type="text" name="mail"></td></tr>
    <tr><th>age:</th><td><input type="text" name="age"></td></tr>
    <tr><th></th><td><input type="submit" value="send"></td></tr>
  </table>
</form>

@endsection

コントローラを修正

    public function index(Request $request)
    {
      return view('hello.index',['msg'=>'フォームを入力']);
    }
    public function post(Request $request){
      $validate_rule=[
        'name'=>'required',
        'mail'=>'email',
        'age'=>'numeric|between:0,150',
      ];
      $this->validate($request,$validate_rule);
      return view('hello.index',['msg'=>'正しく入力された']);
    }

indexメソッドは単純
バリデーション処理はpostメソッドでやってる。

web.php
Route::get('hello', 'HelloController@index');
Route::post('hello', 'HelloController@post');

POST送信されたときにpostメソッドが呼ばれるようにする。
その後/helloにアクセスして確認する。

バリデーションの基本処理

      $validate_rule=[
        'name'=>'required',
        'mail'=>'email',
        'age'=>'numeric|between:0,150',
      ];

検証ルールはこの様になっている。
'age'=>'numeric|between:0,150',のようにルールは|で複数指定できる。

バリデーションの実行

$this->validate($request,$validate_rule);
で実行している。

エラーメッセージと値の保持

先の例ではどんなエラーが起きたのかわからない。何をどう変更すればいいのか、再入力の時に入力値の保持をやっていく

index.blade.php
@section('content')

<p>{{$msg}}</p>
@if(count($errors)>0)
<div >
  <ul>
    @foreach($errors->all() as $error)
    <li>{{$error}}</li>
    @endforeach
  </ul>
</div>
@endif
<form action="/hello" method="post">
  <table>
    @csrf
    <tr><th>name:</th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>
    <tr><th>mail:</th><td><input type="text" name="mail" value="{{old('mail')}}"></td></tr>
    <tr><th>age:</th><td><input type="text" name="age" value="{{old('age')}}"></td></tr>
    <tr><th></th><td><input type="submit" value="send"></td></tr>
  </table>
</form>

@endsection

これでアクセスしてみると今度はエラーの表示がされる。

エラーメッセージ表示の仕組み

@if(count($errors)>0)
<div >
  <ul>
    @foreach($errors->all() as $error)
    <li>{{$error}}</li>
    @endforeach
  </ul>
</div>
@endif

$errorsはバリデーションで発生したエラーメッセージをまとめて管理するオブジェクト
これはバリデーションの機能で組み込まれるため、コントローラで設定する必要はない。

これはエラーの表示をしている。

    @foreach($errors->all() as $error)
    <li>{{$error}}</li>
    @endforeach

$errors->all()でエラーメッセージを配列にまとめて取り出している。

前回送信した値

これはのvalueに前回の値を設定すればいい。

value="{{old('name')}}"

oldメソッドを使っていて、これは引数に入力した項目の古い値を返す。
いずれもコントローラはいらずテンプレだけでできる。

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

【Laravel】保存済みデータを編集/保存/削除する

ほぼほぼ自分用メモです。

編集

編集の画面と処理。

Route

web.php
Route::group(
    ['prefix' => 'contacts', 'middleware' => 'auth'],
    function () {
        Route::get('index', 'ContactFormController@index')->name('contacts.index');
        Route::get('create', 'ContactFormController@create')->name('contacts.create');
        Route::post('store', 'ContactFormController@store')->name('contacts.store');
        Route::get('show/{id}', 'ContactFormController@show')->name('contacts.show');
        Route::get('edit/{id}', 'ContactFormController@edit')->name('contacts.edit');  //追加
    }
);

Controller

ContactFormController.php
//モデルの呼び出し
use App\Models\ContactForm;
//ファサードの呼び出し
use Illuminate\Support\Facades\DB;

public function edit($id)
    {
        $contact = ContactForm::find($id);
        return view('contacts/edit', compact('contact'));
    }

View

show.blade.php
{{-- createで入れた情報の表示 --}}
<div>{{$contact->name}}</div>
<div>{{$gender}}</div>
<div>{{$contact->contact}}</div>

{{-- editページに移動 --}}
<a href="{{route('contacts.edit',[$contact->id])}}" class="btn btn-primary" type="submit">編集する</a>
edit.blade.php
<form method="POST" action="{{route('contacts.edit',['id'=>$contact->id])}}">
    @csrf
    <input class="input-group" type="text" name="name" value="{{$contact->name}}">
    <input class="input-group" type="text" name="email" value="{{$contact->email}}">
    男性:<input type="radio" name="gender" value="0" @if($contact->gender===0)checked @endif>
    女性:<input type="radio" name="gender" value="1" @if($contact->gender===1)checked @endif>
    <input class="input-group" type="text" name="title" value="{{$contact->title}}">
    <textarea class="input-group" name="contact">{{$contact->contact}}</textarea>

    <input class="btn btn-primary" type="submit" value="更新する">
</form>

ラジオボタンはif文で現在のデータを表示する。

保存

編集ができるようになったので、編集したデータをアプデートして表示させます。

Route

web.php
Route::group(
    ['prefix' => 'contacts', 'middleware' => 'auth'],
    function () {
        Route::get('index', 'ContactFormController@index')->name('contacts.index');
        Route::get('create', 'ContactFormController@create')->name('contacts.create');
        Route::post('store', 'ContactFormController@store')->name('contacts.store');
        Route::get('show/{id}', 'ContactFormController@show')->name('contacts.show');
        Route::get('edit/{id}', 'ContactFormController@edit')->name('contacts.edit');
        Route::post('update/{id}', 'ContactFormController@update')->name('contacts.update');  //追加
    }
);

Controller

ContactFormController.php
public function update(Request $request, $id)
    {
        $contact = ContactForm::find($id);

        $contact->name = $request->input('name');
        $contact->email = $request->input('email');
        $contact->title = $request->input('title');
        $contact->gender = $request->input('gender');
        $contact->contact = $request->input('contact');

        $contact->save();

        return redirect('contacts/show/' . $id);
    }

redirectでcontacts/showにリダイレクトさせる。
「.」でidをつなげてるので該当idのページがリダイレクトさせる。

ちゃんと変わってたらおk。

削除

作成したデータを削除します。

Route

web.php
Route::group(
    ['prefix' => 'contacts', 'middleware' => 'auth'],
    function () {
        Route::get('index', 'ContactFormController@index')->name('contacts.index');
        Route::get('create', 'ContactFormController@create')->name('contacts.create');
        Route::post('store', 'ContactFormController@store')->name('contacts.store');
        Route::get('show/{id}', 'ContactFormController@show')->name('contacts.show');
        Route::get('edit/{id}', 'ContactFormController@edit')->name('contacts.edit');
        Route::post('update/{id}', 'ContactFormController@update')->name('contacts.update');
        Route::post('destroy/{id}', 'ContactFormController@destroy')->name('contacts.destroy'); //追加
    }
);

Controller

ContactFormController.php
public function destroy($id)
    {
        $contact = ContactForm::find($id);
        $contact->delete();

        return redirect('contacts/index');
    }

View

destroy.show.php
<form method="POST" action="{{route('contacts.destroy',[$contact->id])}}">
    @csrf
    <button type="submit" class="btn btn-danger" data-id="{{$contact->id}}" onclick="deletePost(this);">削除する</button>
</form>

<script>
    function deletePost(e) {
        if (confirm('本当に削除してもいいですか?')) {
            document.getElementById(('delete_' + e.dataset.id).submit());
        }
    }
</script>

javascriptで削除前に警告を表示しています。

まとめ

メモ程度ですが、参考になれば。

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

【Laravel】保存済みデータを編集/保存する

既に保存されているデータの編集をします。

編集画面

編集画面を作成します。

Route

web.php
Route::group(
    ['prefix' => 'contacts', 'middleware' => 'auth'],
    function () {
        Route::get('index', 'ContactFormController@index')->name('contacts.index');
        Route::get('create', 'ContactFormController@create')->name('contacts.create');
        Route::post('store', 'ContactFormController@store')->name('contacts.store');
        Route::get('show/{id}', 'ContactFormController@show')->name('contacts.show');
        Route::get('edit/{id}', 'ContactFormController@edit')->name('contacts.edit');  //追加
    }
);

Controller

ContactFormController.php
//モデルの呼び出し
use App\Models\ContactForm;
//ファサードの呼び出し
use Illuminate\Support\Facades\DB;

public function edit($id)
    {
        $contact = ContactForm::find($id);
        return view('contacts/edit', compact('contact'));
    }

View

show.blade.php
{{-- createで入れた情報の表示 --}}
<div>{{$contact->name}}</div>
<div>{{$gender}}</div>
<div>{{$contact->contact}}</div>

{{-- editページに移動 --}}
<a href="{{route('contacts.edit',[$contact->id])}}" class="btn btn-primary" type="submit">編集する</a>
edit.blade.php
<form method="POST" action="{{route('contacts.edit',['id'=>$contact->id])}}">
    @csrf
    <input class="input-group" type="text" name="name" value="{{$contact->name}}">
    <input class="input-group" type="text" name="email" value="{{$contact->email}}">
    男性:<input type="radio" name="gender" value="0" @if($contact->gender===0)checked @endif>
    女性:<input type="radio" name="gender" value="1" @if($contact->gender===1)checked @endif>
    <input class="input-group" type="text" name="title" value="{{$contact->title}}">
    <textarea class="input-group" name="contact">{{$contact->contact}}</textarea>

    <input class="btn btn-primary" type="submit" value="更新する">
</form>

ラジオボタンはif文で現在のデータを表示する。

保存画面

編集ができるようになったので、編集したデータをアプデートして表示させます。

Route

web.php
Route::group(
    ['prefix' => 'contacts', 'middleware' => 'auth'],
    function () {
        Route::get('index', 'ContactFormController@index')->name('contacts.index');
        Route::get('create', 'ContactFormController@create')->name('contacts.create');
        Route::post('store', 'ContactFormController@store')->name('contacts.store');
        Route::get('show/{id}', 'ContactFormController@show')->name('contacts.show');
        Route::get('edit/{id}', 'ContactFormController@edit')->name('contacts.edit');
        Route::post('update/{id}', 'ContactFormController@update')->name('contacts.update');  //追加
    }
);

Controller

ContactFormController.php
public function update(Request $request, $id)
    {
        $contact = ContactForm::find($id);

        $contact->name = $request->input('name');
        $contact->email = $request->input('email');
        $contact->title = $request->input('title');
        $contact->gender = $request->input('gender');
        $contact->contact = $request->input('contact');

        $contact->save();

        return redirect('contacts/show/' . $id);
    }

redirectでcontacts/showにリダイレクトさせる。
「.」でidをつなげてるので該当idのページがリダイレクトさせる。

ちゃんと変わってたらめでたし。

まとめ

メモ程度ですが、参考になれば。

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

【Laravel】ミドルウェア

書籍のアウトプットとして

ミドルウェアの利用

ミドルウェアとは

指定のアドレスにリクエストが送られたら何らかの処理を行う仕組みのこと

/***************************/
//リクエスト
/***************************/

↓     ←ミドルウェア

/***************************/
//アクション
/***************************/

↓     ←ミドルウェア

/***************************/
//レスポンス
/***************************/

ミドルウェアの作成

php artisan make:middleware ミドルウェア名

これでHttp/Middlewareに作成される。
ここではHelloMiddlewareという名前で作る。

HelloMiddlewareクラス

作成されたHelloMiddlewareはなんのクラスも継承していない。

handleメソッドについて

これには1つだけメソッドがある。
以下のように定義されている。

    public function handle($request, Closure $next)
    {
        //実行する処理
    }
引数 説明
$request リクエスト情報を管理するRequestインスタンス
$next Closureクラスのインスタンス。

Closureは無名関クラスを表すクラス。
$nextはクロージャでこれを呼び出して実行すると
ミドルウェアからアプリケーションへと送られるリスエスト(Requestインスタンス)を作成できる。

$request->merge(配列)

public function handle($request, Closure $next)
    {
        $data=[
          ['name'=>'taro','mail'=>'taro@example.com'],
          ['name'=>'taro2','mail'=>'taro2@example.com'],
          ['name'=>'taro3','mail'=>'taro@3example.com'],
        ];
        $request->merge(['data'=>$data]);
        return $next($request);
    }

mergeはフォーム送信で送られる値(input値)に値を追加できる。
dataという項目で\$dataの内容が追加される。
コントローラ側では$request->dataで取り出せる。

その後ミドルウェアを登録する。
$routeMiddleware変数の最後に追記する。

app/Http/Kernel.php
'hello'=>\App\Http\Middleware\HelloMiddleware::class,

これで登録完了。

ミドルウェアの実行

次は利用するミドルウェアを呼び出す処理を書いていく。

web.php
//use App\Http\Middleware\HelloMiddleware;を追記
Route::get('hello', 'HelloController@index')->middleware(HelloMiddleware::class);

メソッドチェーンで追加していく。
連続して書くこともできる。

Route::get(...)->middleware(...)->middleware(...);

ビューとコントローラの修正

これでミドルウェアが/helloで動作するようになった。
次は変数\$dataの動作を確認していく。

コントローラを修正する。

    public function index(Request $request)
    {
      return view('hello.index',['data'=>$request->data]);
    }

テンプレを修正する。

@section('content')
<p>ここが本文のコンテンツ</p>  
<table>
  @foreach($data as $item)
  <tr>
    <th>{{$item['name']}}</th><td>{{$item['mail']}}</td>
  </tr>
  @endforeach
</table>
@endsection

/helloにアクセスして確認してみる。

今後DBを使うようになるとミドルウェアがコントローラの負担を減らしてくれる。

リクエストとレスポンスの流れ

今回は「リクエスト」→「処理」の流れだったが
「処理」→「リクエスト」もできる。
つまりアクション後の処理も作成できる。

ミドルウェアのhandleメソッドのデフォルトはこうなっていた。

    public function handle($request, Closure $next)
    {
        return $next($request);
    }

引数として\$requestが渡され、クロージャの戻り値がreturnで返されていた。
この$nextで返されるものはResponseインスタンスだ。
リスエストが送られてからクライアントにレスポンスが返されるまでの流れはこうだ。

  1. リクエストが送られる。
  2. ミドルウェアのhandleが呼びだされる
  3. $nextを実行する。複数のミドルウェアが設定されてるなら、次のミドルウェアのhandleが呼び出される。ないならコントローラのアクションが呼び出される。
  4. アクションメソッドが終わるとともにページがレンダリングされ、レスポンスが生成される。この生成されたレスポンスが$nextの戻り値。
  5. 返されたレスポンスがreturnで返され、クライアントへ返される。

前処理と後処理

この流れを理解するとコントローラの前と後でのミドルウェアの作成方法がわかる。

前処理

先もやったように、必要な処理をすべて実行してから$nextを実行してreturn

    public function handle($request, Closure $next)
    {
        //処理を実行
        return $next($request);
    }

後処理

$nextを実行してレスポンスを受け取ってから処理を実行する。
処理が終わったら保管してあったレスポンスをreturn

    public function handle($request, Closure $next)
    {
        $response=$next($request)
        //処理を実行
        return $response;
    }

レスポンス操作

では後処理のサンプルを作っていく。
HelloMiddlewareクラスを修正

    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $content  = $response->content();
        $pattern  = '/<middleware>(.*)<\/middleware>/i';
        $replace  = '<a href="http://$1">$1</a>';
        $content  = preg_replace($pattern, $replace, $content);
        $response->setContent($content);
        return $response;
    }

処理の流れ

$response = $next($request);

でコントローラのアクションが実行され、レスポンスが代入される。

$content  = $response->content();

コンテンツを取得している。
その後正規表現で置換を行っている。
後はレスポンスにコンテンツを設定してreturn

$response->setContent($content);
return $response;

レスポンスへのコンテンツの設定にはsetContentメソッドを使う。

つぎはテンプレを修正

index.blade.php
@section('content')
  <p>ここが本文のコンテンツ</p>  
  <p>これは<middleware>google.com</middleware></p>
  <p>これは<middleware>yahoo.co.jp</middleware></p>
@endsection

コントローラの修正

    public function index(Request $request)
    {
      return view('hello.index');
    }

今回はコントロー側では何もしていない。
では、/helloにアクセスして確かめる。

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