- 投稿日:2020-07-26T21:33:20+09:00
Vue + Vue Router + Vuex + Laravel のチュートリアル(@MasahiroHarada 様 作成)を進める最中に詰まった部分の原因と対策
はじめに
こちらの記事は、@MasahiroHarada 様が作成された以下の記事をのチュートリアルを、実際に自分が行ってみて、詰まった部分や勘違いしていた部分を、他のチュートリアルに挑戦される方向けに残したものです。
Laravel 6 & PHP 7.4 対応】Vue + Vue Router + Vuex + Laravel チュートリアル(全16回)を書きました。
本当に素晴らしい記事で、Laravel、Vue、spa設計の知見が深まりました。
この場を借りて、改めて感謝申し上げます。※記事の執筆にあたり、一応ご本人から確認はいただいておりますが、共著でもないため、間違いやご指摘、ご意見は全て私の方に直接いただきますよう、お願い申し上げます。
それでは、よろしくお願いします。
私の開発環境と前提
私が使用した開発環境です。
Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (3) SPA開発環境とVue Routerの記事を参考に、Dockerで作成しました。
Laravelは7.19.0、OSはMacです。
詳しいことは上記の記事にまとめてくださっていますが、前提条件としてご了承ください。
次章より、実際に詰まった部分と解決策を述べます。npm run watch で何も表示されない
最初に遭遇したエラーは、(3) SPA開発環境とVue Routerのフロントエンドのビルドの項目で、
npm run watch
を入力しても何も表示されなかったことです。これは、SPAの仕組み上当然のことで、バックエンドの(Laravelの)サーバーを立てていなかったことが原因でした。
ターミナル等でシェルをもう一つ用意し、バックエンドのサーバーを
php artisan serve --host 0.0.0.0 --port 8081
で立ててから、もう一つの方でnpm run watch
を行うと無事表示されました。Illuminate\Foundation\Auth\RegistersUsers.php がない
(4) 認証APIの部分です。
これは、私と同じLaravelの7系、もしくは6系を使っている方は遭遇するかと思います。対策の詳細はこちらの公式にも載っています。
https://readouble.com/laravel/7.x/ja/authentication.html具体的には、以下のコードをcomposerファイルのあるディレクトリで実行すると現れてくれるはずです。
# Laravel6系 composer require laravel/ui:^1.0 --dev # Laravel7系 composer require laravel/ui参考記事
更新! Laravel6/7「make:Auth」が無くなった 〜Laravel6/7でのLogin機能の実装方法〜MyMemoなぜか新規登録ができない
これが個人的には一番びっくりなエラーでした。コードはあっていて新規登録をしようとしても、
POST http://localhost:3000/api/register 405 (Method Not Allowed) message: "The POST method is not supported for this route. Supported methods: GET, HEAD."
というエラーが出ます。これの解決策は、なんとパスワードを8文字以上にすることでした。
Railsのdeviseというログイン機能を作ってくれるライブラリをよく使用していて、そちらは6文字だったので油断しておりました。参考記事
ユーザー認証のパスワード制限の変更コントローラーで処理がされない
チュートリアルを進めていき、理解している部分は基本的にコピペで行っていたのですが、それ通りに貼り付けているはずなのにコントローラーが反応してくれない場面がありました。
原因はDIのし忘れ(namespaceの書き忘れ)でした。
Laravelでは別ファイルから使いたい要素を持ってくるときに、
use App\Http\Requests\StoreComment;
と言った形で主にファイル冒頭に記載をするのですが、内容のコードだけを貼って、こちらをコピペすることを忘れていました。結果、参照ができずにエラーが出たわけです。しっかりと記事を読んで、コピーのし忘れがないか確認しましょう。
Failed to load resource: the server responded with a status of 405 (Method Not Allowed) が出る
これは、ルーティングに誤りがありました。今回のチュートリアルでは、api.phpとweb.php二つのルーティングがあります。apiを叩く処理を間違った方に書いており、このエラーが発生しました。
「ルーティングを書いている場所はあっているか?」チェックをしてみると解決するかもしれません。
エラーメッセージがインポートできない
(8) エラーハンドリングの章で記載ミス?と思われるものがあります。(2020/7/26現在)コメント欄で@MasahiroHarada 様が回答されていますが、一応記事がそのままだったのでこちらにも記載いたしました。
router.jsimport SystemError from './pages/errors/System.vue' // ここのままだとエラーになるので、 // import SystemError from './pages/errors/500.vue' // としてあげましょう /* 中略 */ const routes = [ /* 中略 */ { path: '/500', component: SystemError } ]写真投稿APIのテストが通らない
Dockerで作開発をしていると、 (9) 写真投稿APIのテストが通りません、原因は記事のコメント欄にもあったのですが、一応こちらにまとめます。
基本的には紹介されているこちらの記事通りにやっていただきたいのですが、私はDocker初学者だったので「再ビルドしてください」というのが、どうするのかわかりませんでした。
私の場合
docker build -t vuesplash_vuesplash_web .
で解決しました。(ピリオドも必要です)謝辞
以上が、自分がチュートリアル実行時に遭遇したエラーです。初歩的なミスもあり、そのような振り返り学習ができたという点でも、こちらのチュートリアルは素晴らしかったです…本当にありがとうございました。
- 投稿日:2020-07-26T21:00:51+09:00
MacにLaravelインストールしたメモ
この度初めてMacを購入してLaravelの環境構築を行ったのでメモ。調べながらトライしてなんとか完了。が、2つハマったポイントがありました。
1. システム環境
・macOS Catalina10.15.6
すべてMacのターミナルで作業。
(ちなみにハマった理由の1つがOSのverとターミナルが関係。)2. 手順
Ⅰ.Composerインストール
以下を実行。curl -sS https://getcomposer.org/installer | phpつぎにcomposerをどの作業場所からでも呼べるように設定。
mv composer.phar /usr/local/bin/composerインストール後,以下のコマンドで
composer______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.10.9 2020-07-16 12:57:00上記表示されれば正常にインストール完了。
Ⅱ.Composerを使ってLaravelインストーラーをインストール
以下を実行。
composer global require "laravel/installer"※ハマりポイント1
しかし、ここでエラー出てしまいました。どうもmacにはじめからインストールされているPHPではext-zipに対応してませんよ、ということらしい...(Problem1の2段目の部分)Changed current directory to /Users/ryo3110/.composer Using version ^3.2 for laravel/installer ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for laravel/installer ^3.2 -> satisfiable by laravel/installer[v3.2.0]. - laravel/installer v3.2.0 requires ext-zip * -> the requested PHP extension zip is missing from your system. Installation failed, deleting ./composer.json.これをPHPをインストールし直すことで対応。MacにはHomebrewというパッケージ管理システムがあるのでこちらを利用する。
以下のコマンドでHomebrewをインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"インストールできたらbrewコマンドでphpをインストールする。普段を使用しているので7.4にした。ここは使い慣れているver.でいいはず。
$ brew install php@7.4インストールできたら改めてLaravelインストーラーのインストールを試みる。
composer global require "laravel/installer"無事インストーラーのインストール完了。
Ⅲ.Laravelコマンド使えるようにパスを通す
この時点ではターミナル開いてすぐにLaravelコマンドが使えないのでパスの設定を行う。以下を実行。
echo "export PATH=~/.composer/vendor/bin:$PATH" >> ~/.bash_profile.bash_profileを読み込み。
source ~/.bash_profileこれでターミナルにlaravelと打てばlaravelコマンドが使える。
※ハマりポイント2
しかしターミナルをと閉じると使えなくなってしまう...どうもパスの設定が保存されていないのではと考えひたすら調べる。。。https://www.infoq.com/jp/news/2019/07/macos-ditches-bash-for-zsh/
どうやらCatalinaから標準シェルがbashからzshに変わっていることで.bash_profileを読み込まないのが原因と判明。(Mac初めて買ったのに、変わってるとかそんなん知らん...)後ほど気づいたのですが、そもそも使用不可のコマンド打ったとき、zsh: command not foundと表示されるのでちゃんと確認しておくべきでした...
ともあれ、原因わかったので再度トライ。従来のbashにも設定できるようだが、Appleがzshに切り替えたということで今後しばらくその方針になることを考えて、zshを使う方針で対応。
ターミナルのホームディレクトリに.zshrcをつくる。(vimで作業)
vim .zshrc下記を入力し保存する。
export PATH=$PATH:~/.composer/vendor/binこれでなんとかターミナルを閉じてもすぐにLaravelコマンドが使えるようになった。
- 投稿日:2020-07-26T17:59:18+09:00
Laravelで PhotoSwipeを手っ取り早く使う方法
地味に導入が面倒なのでまとめてみた。
参考
PhotoSwipeSimplify(PhotoSwipeを簡単に使うための超便利なライブラリ(参考サイトこちら)
導入方法
1. npmでインストール
npm install jquery.photoswipe
2. app.jsで読み込む
resource/js/app.jsrequire('photoswipe'); window.photoswipeSimplify = require('photoswipe-simplify');3. img群をdata-pswp要素で囲む
<div data-pswp> ... 画像 ... </div>4. 初期化をしてスタート
photoswipeSimplify.init();ってやれば幸せになるよ。
- 投稿日:2020-07-26T17:26:54+09:00
Laravelでプロジェクト作成~MVC作成 手順、コマンドまとめ
環境
言語:php html
フレームワーク:Laravel
サーバ環境:xampp
DB:MySQL(xamppで管理)
OS:Windows 10※xampp、laravel、composer 環境構築は完了済み。
Laravelプロジェクト作成
laravel new プロジェクト名サーバ起動
php artisan servehttp://localhost:8000/
にて、Laravelページが表示されることを確認。
ここから先MVC作成
コントローラ作成
php artisan make:controller HogeControllerコントローラー追記
app/Http/Controllers/HogeController.php
public function contact() { return view("contact"); //viewファイル"contact.blade.php”呼び出し }ルーティング作成
routes/web.php
Route::get("contact", "HogeController@contact"); // http://localhost:8000/contact が呼ばれたとき、HogeController内contactメソッド呼び出しビュー作成
resources/views/contact.blade.php(手動で新規作成する)
<!DOCTYPE HTML> <html> <head> <title>contact</title> </head> <body> <h1>Hello World!!</h1> </body> </html>マイグレーション
※ユーザテーブルはデフォルトでマイグレーションファイルが作成されている。
マイグレーションファイルの作成
php artisan make:migration create_books_table名前は複数形で作成するのが慣例
マイグレーションファイル書き込み
/database/migrationsフォルダにmigrationファイルが作成される。
この中に、変数を追記する。Schema::create('books', function (Blueprint $table) { $table->id(); $table->string("title"); //追記 $table->text("body"); //追記 //etc... $table->timestamps(); });マイグレーション実行
php artisan migrateマイグレーションが成功しているかの確認
php artisan migrate:statusモデル作成
php artisan make:model Book名前は単数形で書くのが慣例(migrateは複数形)
app/ 直下に Book.phpが作成される。
- 投稿日:2020-07-26T17:19:54+09:00
Laravelで認可(Policy)
認可
簡単に言うと
認証はアクセスしてきているユーザーが誰なのかを認識するもの
認可はアクセスしてきたユーザーに操作を許可するかどうかを判定するもの
ですPolicyを使った認可
簡単に言うと
EloquentのModelに紐づく真偽値を返す関数(Policy)を作っておき、それを簡単に呼び出せるようにしておくようなものです前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っていますLaravelで認可(Gate)
本記事は上記が完了している前提で書かれています
今回使うカラムも上記記事で作成済みですPolicyの作成
今回は下記記事で作成したTable2というModelを使います
Laravelでデータベースを操作する(Eloquent編)コマンドラインで
cd sample
php artisan make:policy Table2Policy --model=Models\Table2
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Policies/Table2Policy.phpが現れます/sample/app/Policies/Table2Policy.php修正
Table2Policy.php‥‥ public function create(User $user) { return $user->rank >= 2; } public function update(User $user, Table2 $table2) { return $user->rank >= $table2->int_col; } ‥‥createメソッドとupdateメソッドを修正しました
Policyのメソッドの第一引数は必ず、ユーザーインスタンスになります下記7メソッドが自動的にできあがっていると思います
viewAny
view
create
update
delete
restore
forceDelete
これらはコントローラーをつくるときにphp artisan make:controller XXXController --resource
のように--resource
オプションを付けて作成したリソースコントローラーの各メソッドに対応しています
コントローラメソッド ポリシーメソッド index viewAny show view create create store create edit update update update destroy delete コントローラーのindexメソッドではPolicyのviewAnyメソッドを使ってください
コントローラーのshowメソッドではPolicyのviewメソッドを使ってください
ということですPolicyの登録
/sample/app/Providers/AuthServiceProvider.php修正
AuthServiceProvider.php‥‥ protected $policies = [ 'App\Models\Table2' => 'App\Policies\Table2Policy', ]; ‥‥
$policies
配列に要素を追記しました
keyがModel、valueがPolicyになります
これでLaravelアプリケーションの中でPolicyを簡単に呼び出せるようになりますControllerにメソッド追加
(1) use文追記
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Models\Table2;
(2) /sample/app/Http/Controllers/SampleController.phpにgate1メソッド、gate2メソッドを追記
public function policy1() { return view('sample.policy1'); } public function policy2(Request $request) { $int_col = $request->input('int_col'); $user = Auth::user(); $table2 = new Table2(); $table2->int_col = $int_col; if (is_null($user) || !$user->can('create', Table2::class)) { return redirect('sample/policy1')->withInput(); } if (is_null($user) || !$user->can('update', $table2)) { return redirect('sample/policy1')->withInput(); } $data = ['table2' => $table2]; return view('sample.policy2', $data); }Policyは
$user->can
で呼べます
第一引数に与えた文字列はPolicyに定義したメソッド名です
第二引数はPolicyに定義したメソッドの第二引数になります
第二引数を定義していないPolicyの場合第二引数にはクラス名を渡します
Policyの第一引数は$user
になります
$user->can
はPolicyが返す真偽値がそのまま戻り値になります(2) /sample/routes/web.phpに下記を追記
Route::get('sample/policy1', 'SampleController@policy1');
Route::get('sample/policy2', 'SampleController@policy2');
viewの作成
(1) /sample/resources/views/sample/policy1.blade.php
policy1.blade.php<html> <head> <title>sample</title> </head> <body> <form action="{{ url('sample/policy2') }}" method="get"> <div>int_col<input type="text" name="int_col" value="{{ old('int_col') }}"></div> <input type="submit" > </form> </body> </html>(2) /sample/resources/views/sample/policy2.blade.php
policy2.blade.php<html> <head> <title>sample</title> </head> <body> <div> @can('create', App\Models\Table2::class) can create @elsecan('update', $table2) can update @else else @endcan </div> <div> @cannot('create', App\Models\Table2::class) cannot create @elsecannot('update', $table2) cannot update @else else @endcannot </div> </body> </html>blade内でPolicyを使うにはcanやcannotで呼び出せます
@can
や@cannot
を使うことで、更新ボタンを特定のユーザーにだけ表示させたり、または、逆に非表示にしてりできます動作確認
usersテーブルのrankカラムの値を適当な値にupdateします
update users set rank = 4;ログインします
http://localhost/laravelSample/
右上のLOGINからログインします
http://localhost/laravelSample/sample/policy1
rankを4にupdateしてので
5以上の値を入力して送信ボタンをクリックするとpolicy1にリダイレクトされ先に進めないと思います
4以下の値を入力して送信ボタンをクリックするとpolicy2に遷移できます
今回はサンプルのため入力値のエラーチェックを一切行っていないので、gate1の入力欄には数値を入れてください。数値でない場合、制御されていない型エラーになります
実際にシステムを開発するときはちゃんとエラーチェックを入れましょう
エラーチェックの実装の仕方は下記に書いてあります
Laravelで入力値エラーチェック(validate)を実装する
- 投稿日:2020-07-26T15:49:58+09:00
日本語諸方言コーパスをDB化して遊ぶ (3) PHP Laravel で操作する
データベースに慣れるために、「日本語諸方言コーパス (COJADS) 」の元データをデータベース化してみました。第3回は前回作成した SQLite3 データベースを PHP Laravel で操作するところまで。完全に自分用の作業メモで、説明もいろいろ足りていないと思いますが、ご容赦ください。
Laravel の設定
Laravel は PHP のフレームワークのひとつです。そんな凝ったものは作らないので素の PHP でもいいんですが、Laravel の案件も多いし、せっかくなので Laravel を使ってみます(使ったことないけど、Ruby on Rails みたいなもんだろうという軽い気持ち)。
PHP と Laravel の導入
Laravel は PHP のフレームワークなので、まず PHP 環境を作って、依存関係管理の Composer を利用して Laravel を導入していきます。PHP 環境は XAMPP にしました。Windows 環境なのでインストーラーでさくっとインストールします(今回は PHP 7.4.8、Laravel 7.21.0 を使用しています)。
SQLite の有効化
SQLite をデータベースとして使えるように PHP の設定を変更します。私の環境では XAMPP でインストールした時点で有効化されていましたが、念のため php.exe と同じフォルダの設定ファイル php.ini を確認して、以下の行が
;
でコメントアウトされていないことを確認しておきます。php.iniextension=pdo_sqliteプロジェクトの作成
Composer で適当な場所に Laravel プロジェクトを作成します。今回は XAMPP フォルダに
_projects
フォルダを作成し、その中でcojads
プロジェクトを管理することにします。cmdC:\xampp\_projects>composer create-project laravel/laravel --prefer-dist cojadscojads プロジェクトの設定から、データベースとして SQLite を使用するように変更しておきます。
DB_CONNECTION
をsqlite
にして、それ以降のデータベースの設定項目は不要なので、削除するかコメントアウトします。.env内DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret ↓↓↓次のように変更する↓↓↓ DB_CONNECTION=sqlite #DB_HOST=127.0.0.1 #DB_PORT=3306 #DB_DATABASE=homestead #DB_USERNAME=homestead #DB_PASSWORD=secret
/config/database.php
のデフォルト設定も、mysql になっているので sqlite に変更しておきます。config/database.php内'default' => env('DB_CONNECTION', 'mysql'), ↓↓↓次のように変更する↓↓↓ 'default' => env('DB_CONNECTION', 'sqlite'),データベースの設定
既存データベースのマイグレーション
まずはマイグレーションを行ないます。前回作成した
cojads.sqlite3
をdatabase.sqlite
に改名して 1プロジェクトのdatabase
フォルダに配置します。マイグレーションはphp artisan migrate
コマンドで行なえます。cmdC:\xampp\_projects\cojads>php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.32 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.13 seconds)モデルの作成
次に Model を設定します。初期段階では Model 用のフォルダもないので、ひとまず
app
フォルダにModels
フォルダを新規作成し、以下のようにテーブルごとにモデルを作成していきます。cmdphp artisan make:model Models/prefecture php artisan make:model Models/location php artisan make:model Models/speaker php artisan make:model Models/discourse php artisan make:model Models/utteranceそうすると、
Models
フォルダ内にそれぞれのモデルのクラス設定ファイルが作成されています。作成した段階ではクラス宣言のみで何の役にも立たないので、たとえばspeaker
テーブルなら以下のように属性とゲッターメソッドを書き込んでいきます。$guarded
には主キーspeakerId
を設定します。app/Models/speaker.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; class Speaker extends Model{ protected $table = 'speaker'; protected $guarded = array('speakerId'); public $timestamps = false; public function getData(){ $data = DB::table($this->table)->get(); return $data; } }ルーティングとサンプルページの作成
今回はデータベースの中身を閲覧できるシンプルなページを作ります。今回は「話者 (speaker) 」を閲覧できるページを作りましょう。まず
routes/web.php
にルーティングを追加します。以下ではcojads/speaker
に GET アクセスするとCojadsController
コントローラーのspeaker
アクションを実行するようにしています。web.phpRoute::get('cojads/speaker', 'CojadsController@speaker');次にルーティングに沿って
CojadsController
コントローラーを新規作成して……cmdphp artisan make:controller CojadsControllerさっき指定した
Speaker
モデルに関するspeaker
アクションだけ作ります。ここではデータを取得してcojads.speaker
ビュー、つまりviews/cojads
フォルダの中のspeaker
という名前のファイルに値を送るようにしています。app/Http/Controllers/CojadsController.php<?php namespace App\Http\Controllers; use App\Models\Speaker; class CojadsController extends Controller{ public function speaker(){ $md = new Speaker(); $data = $md->getData(); return view('cojads.speaker', ['data' => $data]); } }最後に今のアクションの指定に沿って
/resources/views
フォルダにcojads
フォルダを作り、その中にビューを作成していきます。ここでは blade 記法を使うのでspeaker.blade.php
を作成して、以下のようにテーブルを作ってspeaker
テーブルの内容を順に描画していきます。/resouces/views/cojads/speaker.blade.php<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Show Speakers</title> </head> <body> <table> <thead> <tr> <th>話者ID</th> <th>性別</th> <th>生年</th> </tr> </thead> <tbody> @foreach($data as $d) <tr> <td>{{$d->speakerId}}</td> <td>{{$d->speakerSex}}</td> <td>{{$d->speakerBirthyear}}</td> </tr> @endforeach </tbody> </table> </body> </html>ここまでの作業が済んだら、正しく表示されるか確認します。
php artisan serve
を実行してローカルサーバを立ち上げて……C:\xampp\_projects\cojads>php artisan serve Laravel development server started: http://127.0.0.1:8000先ほどルーティングした通り
http://127.0.0.1:8000/cojads/speaker
にアクセスします。きちんと表示されていますね( CSS は適当にあてています)。
次回予告
次回は検索機能など、もうちょっとリッチな機能を実装します。
これは Laravel がデフォルトで
database
フォルダのdatabase.sqlite
を参照する設定になっているからです。ファイル名を変えたくない場合は、config/database.php
の内でdatabase.sqlite
を参照している部分を任意のファイル名に変更するか、ルートの.env
内でデータベースの場所をフルパスで指定する必要があります。たとえばDB_DATABASE=C:\xampp\_projects\cojads\database\cojads.sqlite3
など。 ↩
- 投稿日:2020-07-26T13:43:55+09:00
LaravelでAPIを作成
- 投稿日:2020-07-26T13:37:02+09:00
HerokuにデプロイしたLaravelアプリをURL正規化する
はじめに
HerokuにデプロイしたLaravelのWebサービスをURL正規化しようとしましたが、
.htaccessのリダイレクトが有効にならずにハマったのでMiddlewareでリダイレクトしました。やりたいこと
- 「/index.php」を「/」にリダイレクトしたい
- Herokuドメイン「***.herokuapp.com」を独自ドメイン「***.com」にリダイレクトしたい
この記事で説明しないこと
- Herokuの独自ドメイン設定
- 独自ドメインSSL化
環境
Laravel
$ php artisan --version Laravel Framework 7.19.0作業内容
URL正規化用のMiddleware登録
GithubからMiddlewareをダウンロード
GithubにLaravelでURL正規化する為のMiddlewareを公開されている方がいたので使用させて頂きました。
- 参考:Laravel Middleware で URL を正規化する例です。ダウンロードしたファイルを以下フォルダへコピーします。
. ├── app │ └── Http │ └── Middleware │ └── Normalize.phpNormalize.phpを変更
handle()
先頭に独自ドメインへのリダイレクトを追加します。
※ドメインの***の部分は読み替えてください。/app/Http/Middleware/Normalize.php/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // ここから if ($_SERVER['HTTP_HOST'] == '***.herokuapp.com') { return redirect()->to('https://***.com' . $request->getRequestUri(), 301, [], $secure = true); } // ここまで $url = $_SERVER['REQUEST_URI']; // PHP 標準のリクエストを使用 $normalized = $this->normalize($url); if ($url != $normalized) { header('Location: ' . $normalized, true, 301); // PHP 標準のリダイレクトを使用 exit(); } ....normalize()
今回はパスの末尾をスラッシュで置き換える必要が無かったためスラッシュ追加部分をコメントアウトしました。
また、ローカルではlocalhost:8080ポートで動かしているためhostとportを追加しました。/app/Http/Middleware/Normalize.php/** * @param $url * @return string */ private function normalize($url) { // 'host'、'port'を追加 $elements = ['scheme', 'host', 'port', 'path', 'query', 'fragment']; $isHtmlEncoded = $url !== ($decoded = htmlspecialchars_decode($url)); $url = $decoded; $parsed = parse_url($url); foreach ($elements as $element) { $parsed[$element] = $parsed[$element] ?? ''; } parse_str($parsed['query'], $params); preg_match('/(.*)\/(.*)/', $parsed['path'], $matches); $dirname = $matches[1] ?? ''; $dirname .= '/'; $basename = $matches[2] ?? ''; /* 今回不要のためコメントアウト // パス末尾に / を追加 if ($basename !== '' && mb_strpos($basename, '.') === false) { $dirname .= $basename . '/'; $basename = ''; } */ // index.* を削除 $basename = preg_replace('/^index\.(.*)/', '', $basename); // パスの // -> / 置き換え $dirname = preg_replace('/\/\/+/', '/', $dirname); // クエリ並び替え ksort($params); $parsed['scheme'] .= empty($parsed['scheme']) ? '' : '://'; // 'port'を追加 $parsed['port'] = empty($parsed['port']) ? '' : ':'.$parsed['port']; ....Middlewareを登録
Normalizeをグローバルミドルウェアとして登録します。
/app/Http/Kernel.phpprotected $middleware = [ .... \App\Http\Middleware\Normalize::class, // <= 追記 ];確認
あとはHerokuへデプロイしリダイレクトが確認できれば完了です。
参考にしたサイト
- 投稿日:2020-07-26T13:37:02+09:00
HerokuにデプロイしたLaravelアプリのURLを正規化する
はじめに
HerokuにデプロイしたLaravelのURLを正規化しようとしましたが、
.htaccessのリダイレクトが有効にならずにハマったのでMiddlewareでリダイレクトしました。やりたいこと
- 「/index.php」を「/」にリダイレクトしたい
- Herokuドメイン「***.herokuapp.com」を独自ドメイン「***.com」にリダイレクトしたい
この記事で説明しないこと
- Herokuの独自ドメイン設定
- 独自ドメインSSL化
環境
Laravel
$ php artisan --version Laravel Framework 7.19.0作業内容
URL正規化用のMiddleware登録
GithubからMiddlewareをダウンロード
GithubにLaravelでURL正規化する為のMiddlewareを公開されている方がいたので使用させて頂きました。
- 参考:Laravel Middleware で URL を正規化する例です。ダウンロードしたファイルを以下フォルダへコピーします。
. ├── app │ └── Http │ └── Middleware │ └── Normalize.phpNormalize.phpを変更
handle()
先頭に独自ドメインへのリダイレクトを追加します。
※ドメインの***の部分は読み替えてください。/app/Http/Middleware/Normalize.php/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // ここから if ($_SERVER['HTTP_HOST'] == '***.herokuapp.com') { return redirect()->to('https://***.com' . $request->getRequestUri(), 301, [], $secure = true); } // ここまで $url = $_SERVER['REQUEST_URI']; // PHP 標準のリクエストを使用 $normalized = $this->normalize($url); if ($url != $normalized) { header('Location: ' . $normalized, true, 301); // PHP 標準のリダイレクトを使用 exit(); } ....normalize()
今回はパスの末尾をスラッシュで置き換える必要が無かったためスラッシュ追加部分をコメントアウトしました。
また、ローカルではlocalhost:8080ポートで動かしているためhostとportを追加しました。/app/Http/Middleware/Normalize.php/** * @param $url * @return string */ private function normalize($url) { // 'host'、'port'を追加 $elements = ['scheme', 'host', 'port', 'path', 'query', 'fragment']; $isHtmlEncoded = $url !== ($decoded = htmlspecialchars_decode($url)); $url = $decoded; $parsed = parse_url($url); foreach ($elements as $element) { $parsed[$element] = $parsed[$element] ?? ''; } parse_str($parsed['query'], $params); preg_match('/(.*)\/(.*)/', $parsed['path'], $matches); $dirname = $matches[1] ?? ''; $dirname .= '/'; $basename = $matches[2] ?? ''; /* 今回不要のためコメントアウト // パス末尾に / を追加 if ($basename !== '' && mb_strpos($basename, '.') === false) { $dirname .= $basename . '/'; $basename = ''; } */ // index.* を削除 $basename = preg_replace('/^index\.(.*)/', '', $basename); // パスの // -> / 置き換え $dirname = preg_replace('/\/\/+/', '/', $dirname); // クエリ並び替え ksort($params); $parsed['scheme'] .= empty($parsed['scheme']) ? '' : '://'; // 'port'を追加 $parsed['port'] = empty($parsed['port']) ? '' : ':'.$parsed['port']; ....Middlewareを登録
Normalizeをグローバルミドルウェアとして登録します。
/app/Http/Kernel.phpprotected $middleware = [ .... \App\Http\Middleware\Normalize::class, // <= 追記 ];確認
あとはHerokuへデプロイしリダイレクトが確認できれば完了です。
参考にしたサイト
- 投稿日:2020-07-26T13:10:33+09:00
How to make a file URL copy button (File Upload Site #2)
今回はファイルダウンロードリンクをコピーするボタンを作ります。
1.Routeweb.phpRoute::get('files/uploadedfiles/{name}', 'FilesController@copy')->name('copyfile');2.ボタン
home.blade.php<input value="{{ route('copyfile', $file->id)}}" id="copy_{{ $file->id }}" type="text"> <button value="copy" class="btn btn-link" onclick="copyToClipboard('copy_{{ $file->id }}')">Copy!</button>3.Controller App->Http->Controllers->FilesController.php に
FilesController.phppublic function copy($url) { return Storage::url('/files/uploadedfiles/' . $url->name); }4.Javascript を view ファイルに入れる
home.blade.phpfunction copyToClipboard(id) { document.getElementById(id).select(); document.execCommand('copy'); }以上です。
- 投稿日:2020-07-26T11:41:59+09:00
Laravel + React環境にESlintとPrettierを導入する
始めに
以下はLaravel + Reactの構成で、
Eslint
とPrettier
を導入する流れをメモした記事となります。bladeを使わずに、ReactやVueを利用するプロジェクトも増えてきてると聞いて、では、ESlintやPrettierを導入する時の手順はどうするんだろう?という事で、ちょっと試してみました。
Laravelのバージョンは、
5.7
です。
Laravel + Reactの構成で、Linterを導入したい人は、多少参考になるのではないかと思います。そもそもESlintって?
ESlintとは、JavaScriptのための静的解析ツールで、シングルクォートやスペースの記法のルールを統一したり、単純な構文エラーを検出してくれたりします。
ルールは細かく設定できるので、各プロジェクトによって固有のコーディング規約を定義することもできるので便利です。
詳しくは公式を...
ESlintそもそもPrettierって?
こちらは、Node.js上で動作するフォーマッターです。
インデントや、改行コードなどの基本的な設定をして、定義したフォーマットに従って自動的に整形してくれます。
Linterと役割が、重複する部分もありますが、Linterだけで整形できない部分もカバーしてくれたりします。(1行の長い文字列を整形する設定ができるなど)コードのフォーマットに関しては、Prettierで行い、構文チェックはESlintで行うという形で併用するのが良いかと思います。
こちらも詳しくは公式を...
Prettierなんで導入するの?
上記のようなLinterとFormatterを導入してない状態で、開発をしている方は経験あるかもしれませんが、さまざまな書き方が混在し、1ファイルの中でも、複数の記法が混在し、統一性のない読みづらいコードとなってしまうことがあります。
あれ? シングルクォート、ダブルクォートが混在してる...
おぉ...パスカルケース、キャメルケースが混在してる...何か意図があるのかなぁ...?
ん? セミコロンつけるの?つけないの?...などこのような状態で開発が続いてしまうと、可読性が低く、メンテナンス性の悪いコードになってしまいます。また、プルリク時に、コーディング規約の議論に時間を奪われてしまうことも度々発生します。
フォーマットや命名規則は、プロジェクトに関わる開発者間で統一し、コードリーディング/レビュー時の可読性をあげることは、開発のスピード感をあげる上で重要です。それによって、開発者はコードスタイルに気をとらわれることなく、本質的なコーディングにフォーカスすることができます。
ESlintやPrettierのような優秀なフォーマッターが用意されてるので、それに頼って、可読性の高い、後から入ってきたメンバーに対しても優しいコードにしましょう。ツールに任せられることは優秀なツールに任せちゃいましょう。
Laravel+ReactのプロジェクトにESlintとPrettierを導入する
では、早速導入してみましょう。
まずはnpmコマンドでパッケージをインストール。
各環境で必要に応じて、パッケージをインストールして下さい。パッケージをインストールnpm install eslint eslint-loader eslint-plugin-react eslint-plugin-prettier eslint-config-prettier --save-dev
上記インストールが完了したら、
.eslintrc.json
を作成します。
これはESlintの設定ファイルです。.eslintrc.jsonを作成$ cd LaravelProject $ touch .eslintrc.jsoneslintrc.json{ "env": { "es6": true, "commonjs": true, "browser": true // Globalオブジェクト「window」「document」を許可 }, "extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:prettier/recommended" ], "settings": { "react": { "pragma": "React", "version": "detect" } }, "parser": "babel-eslint", "parserOptions": { "sourceType": "module" }, "rules": { "prettier/prettier": [ "error", { "printWidth": 120, "tabWidth": 2, "trailingComma": "all", "bracketSpacing": true, "singleQuote": true, "semi": false } ] } }LaravelでESlintを使用するよう設定を変更する
Webpackが定義したルールをを元に、ファイル変更を監視してくれるように、
webpack.mix.js
を編集します。以下を参考にしています。
Laravel Mix Eslint Configwebpack.mix.jsconst mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel application. By default, we are compiling the Sass | file for the application as well as bundling up all the JS files. | */ //本番環境ではESLintは使用しません if (!mix.inProduction()) { mix.webpackConfig({ module: { rules: [ { enforce: 'pre', exclude: /node_modules/, loader: 'eslint-loader', test: /\.(js|jsx)?$/, options: { fix: true, cache: false, } } ] } }) }これでセットアップは完了です。
実際に試してみる
以下のような
セミコロン
のあるファイルがあります。
しかし、このファイルは、セミコロン
を許可しないルールが定義されてる場合、コーディング規約に則っていないコーディングをしているということになります。App.jsimport React from 'react'; import ReactDOM from 'react-dom'; import BooksApp from './BooksApp'; const App = () => { return ( <div> <BooksApp /> </div> ); }; export default App; if (document.getElementById('app')) { ReactDOM.render(<App />, document.getElementById('app')); }以下のコマンドを打ってみます。
eslint resources/js/components/App.js
すると、以下のようにコンソールにエラーが表示されます。
見るとセミコロンを削除して下さいと言われてますね。
この場合、いちいち手動で直すの面倒ですよね?その場合、以下コマンドを入力して下さい。
これによって、Eslint
とPrettier
が同時に実行されます。
(= 構文チェックとコードの整形が同時にできる)
これは、先ほどインストールしたeslint-config-prettier
によって実現できることです。eslint resources/js/components/App.js --fix
すると、リアルタイムに、上記
App.js
にあった余計なセミコロンが削除されます。
もう一度、以下コマンドを入力してみましょう。eslint resources/js/components/App.js
すると何もエラーが返ってこない状態になっています。
ここは個々のプロジェクトによって状況が異なるのでご自身の環境に読み替えてみて下さい。ワイルドカードも使えます。
eslint resources/js/components/*.js eslint resources/js/components/*.js --fix
最後に
以上で、
*.js
や*.jsx
ファイルに対して、ESlintとPrettierを導入することができました。
上記手順で、プロジェクトのコーディング規約を定義すれば、開発者間のコーディングスタイルの差異を統一することができるようになります。実際のプロジェクトでは、Gitフックなど使って、コミット時に、ESlintとPrettierを実行するという設定もするかなと思います。
- 投稿日:2020-07-26T07:47:08+09:00
Laravel 認証機能 (インストール編)
認証機能の追加
Laravel6から仕様が変更され、追加手順が変わったようですね。
→ここではLaravel7で操作しています。手順概要
- ライブラリ「laravel/ui」をインストール。
- 認証機能に必要なファイルをダウンロード。
手順詳細
1.ターミナル(コマンド)から、ライブラリ「laravel/ui」をインストール
composer require laravel/ui2.ターミナル(コマンド)から、認証機能に必要なファイルをダウンロード
php artisan ui vue --auth認証機能に必要な更新が行われます。
→ファイルの追加、編集。
3.更新に成功すると、右上に「LOGIN」「REGISTER」が追加されます。