- 投稿日:2020-10-14T23:16:06+09:00
Laravel:componentの設定
【概要】
1.componentフォルダの作成
2.該当のblade.phpで呼び出し
3.開発環境
1.componentフォルダの作成
そもそもコンポーネントとは、レイアウトを最初から記述するために省き冗長にならないように部品のように使える仕組みです。ヘッター、フッターはどこのページにいっても同じデザインで使いたい場合に各レイアウトを統一する時に使用することが多いです。
viewsフォルダにcomponentsフォルダを作成します。さらにcomponentsフォルダの中に、適当なblade.phpファイルを作成します。
resorces/components/message.blade.php<div class="message"> <p class="msg_title">{{$msg_title}}</p> <p class="msg_content">{{$msg_content}}</p> </div>
2.該当のblade.phpで呼び出し
resorces/views/hoge/index.blade.php<html> <head> @component('components.message') #---❶ @slot('msg_title') #---❷ こちらにメッセージを入力してください。 @endslot #---❷ @slot('msg_content') メッセージの内容。 @endslot @endcomponent #---❶ </html> </head>❶:コンポーネントを使用するためにどのフォルダのどのファイルを使用するかを決めています。"components"ファイルの、"message.blade.php"なので、('components.message')とコーディングしています。範囲の終わりには@endcomponentで括れます。
❷:massage.blade.phpの{{$msg_title}}、{{$msg_content}}の変数を使用するために記述しています。cssが反映された状態でindex.blade.phpにそのまま使用できます。@slot(名前)でそのまま使用できます。 @endslotで括れます。
3.開発環境
PHP 7.4.10
Laravel 8.9.0
Apache 2.4.41
- 投稿日:2020-10-14T22:01:57+09:00
Laravel アウトプット
- 投稿日:2020-10-14T21:52:58+09:00
Vue-Laravel→Heroku 実践ミニマル必要情報
私のスタイル
初めまして。翁と申します。
ミニマルで強迫観念やストレスなく、かつ最大限を提供する
"Huge Minimalism"
を提唱し、スタイルとして活動させていただいてます。
お手柔らかによろしくお願いいたします。あくまで"より高みへ。"を意識しており
一記事執筆5分以内と制限しております。
ご理解いただけたらと思います。デプロイまで
1.ローカルコミット
git init git add . git commit -m "first commit"//ここで行うことで自動でデプロイ先が設定されます。 heroku create2.デプロイ
//行く先確認 >git remote -v heroku https://git.heroku.com/~~.git (fetch) heroku https://git.heroku.com/~~.git (push)//Herokuにデプロイ git push heroku master//App keyを設定する。 //これをする前はアクセスしても500エラーになるはず >php artisan --no-ansi key:generate --show >heroku config:set APP_KEY="一つ上の結果"//Githubへと //originを設定 >git remote add origin https://github.com/~~/~~.git //行く先確認 >git remote -v heroku https://git.heroku.com/~~.git (fetch) heroku https://git.heroku.com/~~.git (push) origin https://github.com/~~/~~.git (fetch) origin https://github.com/~~/~~.git (push) //デプロイ >git push origin master
- 投稿日:2020-10-14T21:52:58+09:00
Vue-Laravel→Heroku -デプロイまで-
私のスタイル
初めまして。翁と申します。
ミニマルで強迫観念やストレスなく、かつ最大限を提供する
"Huge Minimalism"
を提唱し、スタイルとして活動させていただいてます。
お手柔らかによろしくお願いいたします。あくまで"より高みへ。"を意識しており
一記事執筆5分以内と制限しております。ご理解いただけたらと思います。デプロイまで
1.ローカルコミット
基本ルートディレクトリでコマンドを打っていきます。
```git init
git add .
git commit -m "first commit"
```//ここで行うことで自動でデプロイ先が設定されます。 >heroku create.git/config[remote "heroku"] url = https://git.heroku.com/okinaofficial.git fetch = +refs/heads/*:refs/remotes/heroku/*2.デプロイ
//行く先確認 >git remote -v heroku https://git.heroku.com/~~.git (fetch) heroku https://git.heroku.com/~~.git (push)//Herokuにデプロイ >git push heroku master//App keyを設定する。 //これをする前はアクセスしても500エラーになるはず >php artisan --no-ansi key:generate --show >heroku config:set APP_KEY="一つ上の結果"//Githubへと //originを設定 >git remote add origin https://github.com/~~/~~.git //行く先確認 >git remote -v heroku https://git.heroku.com/~~.git (fetch) heroku https://git.heroku.com/~~.git (push) origin https://github.com/~~/~~.git (fetch) origin https://github.com/~~/~~.git (push) //デプロイ >git push origin master
- 投稿日:2020-10-14T16:57:37+09:00
Monolog使ってバッチのログをDBに出力する
あらすじ
業務でLaravel使っていたある日のこと。
元々ログはMonologを使って、ログ用のテーブルに出力していました。バッチで出したログもそのテーブルに出す予定だったのですが、バッチログ用のテーブルを新たに作ってそっちに出力したいとのこと。
というわけで、調査のまとめとして投稿することにしました。
環境
- Laravel7
- MariaDB
新規作成・編集するもの
Monologはインストール済みとして考えます。
なかったらComposer使って入れてください。マイグレーションファイル
Artisanコマンドを使ってサクっと作ります。
カラムは一先ず次のようにしていますが、各自の好きに設定して下さい。
- batch_name
- 動いたバッチの名前
- level
- ログレベル。成功なら200, エラーなら400が入る(その他の番号は分かんないです)
- level_name
- DEBUG, INFO, ERRORと言ったログレベルの区分
- start_time
- バッチ処理が始まった時間
- end_time
- バッチ処理が終わった時間
- message
- ログメッセージ
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateBatchLogsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('batch_logs', function (Blueprint $table) { $table->id(); $table->string('batch_name'); $table->string('level'); $table->string('level_name'); $table->datetime('start_time'); $table->datetime('end_time'); $table->string('message'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('batch_logs'); } }.env
DB_BATCH_LOG_TABLE
以外は最初からある項目です。環境に合わせて記述します。# いつものDB設定 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=hogeeeeee DB_USERNAME=root DB_PASSWORD=1234 # バッチログの出力先テーブル DB_BATCH_LOG_TABLE=batch_logsconfig/logging.php
configファイルにバッチログ用の設定を追加
handler
の部分のクラスはこれから新しく作ります。また、下記の参考記事のように
env()
の記述はconfig以外に書かないようするため、handler_with
にenvの情報を書きます。
handler_with
で書かれた情報は、handler
で指定したクラスのコンストラクタで受け取ることができます。'batch' => [ 'driver' => 'monolog', 'handler' => BatchMonologHandler::class, # ← これから新しく作成します 'handler_with' => [ # ← 'handler'で指定したクラスのコンストラクラで受け取り可 'table' => env('DB_BATCH_LOG_TABLE', 'batch_logs'), 'connection' => env('DB_LOG_CONNECTION', env('DB_CONNECTION', 'mysql')), 'ratio' => env('DB_LOG_FLUSH_RATIO', 100), 'limit' => env('DB_LOG_PRESERVE_DAYS', 30) ], ],Loggers/BatchMonologHandler
下記の記事を参考にしました。
Laravel5.6でログをデータベースに記録するnamespace App\Loggers; use Illuminate\Support\Facades\DB; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; class BatchMonologHandler extends AbstractProcessingHandler { protected $table; protected $connection; protected $ratio; protected $limit; public function __construct(string $table, string $connection, string $ratio, int $limit, $level = Logger::DEBUG, $bubble = true) { $this->table = $table; $this->connection = $connection; $this->ratio = $ratio; $this->limit = $limit; parent::__construct($level, $bubble); } protected function write(array $record): void { $data = [ 'batch_name' => $record['context']['batch_name'], 'start_time' => $record['context']['start_time']->format('Y-m-d H:i:s'), 'end_time' => $record['context']['end_time']->format('Y-m-d H:i:s'), 'message' => $record['message'], 'level' => $record['level'], 'level_name' => $record['level_name'], ]; DB::connection($this->connection)->table($this->table)->insert($data); $ratio = $this->ratio; if (rand(0, $ratio - 1) == 0) { $this->deleteOld(); } } protected function deleteOld() { $limit = $this->limit; $date = date('Y-m-d H:i:s', strtotime("-$limit days")); DB::connection($this->connection)->table($this->table)->where('created_at', '<', $date)->delete(); } }BatchTest
バッチ処理を書くクラスです。Artisanコマンドで作成します。
Logファサードを使ってログを書いていますが、普通に書いてしまうと.envの
LOG_CHANNEL
で設定されているものが適用されてしまいます。
そのためLog::channel('batch');
で新しく記述した設定を使うようにしています。また、ログを残すコードの第1引数は
message
です。他の情報は第2引数の配列で追加しています。namespace App\Console\Commands; use App\Models\Logs; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; class BatchTest extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'batch:test'; /** * The console command description. * * @var string */ protected $description = 'batch log test command'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return int */ public function handle() { // config/logging.phpで設定したものを使用する $batch_log = Log::channel('batch'); $start_time = Carbon::now(); sleep(5); $end_time = Carbon::now(); // 第1引数はmessage。他は第2引数の配列にする $batch_log->info('test batch start', [ 'batch_name' => 'test_batch', 'start_time' => $start_time, 'end_time' => $end_time, ]); return 0; } }結果
batch_logsテーブルには画像のようなレコードが追加されていました。
悩んだとこ
Log::info('hoge')
のようなログ出力はよくやりますが、第2引数に配列を指定をするのはやったことなかったです。
なので、BatchMonologHandlerクラスのwtiteメソッドで「batch_nameなんてねーよ」って怒られた時は悩みました。配列で指定した内容をどこから取得するのは分かってなかったんです。
print_r($record)
で中身を見るとcontextキーの中に含まれていたので解決できました。まとめ
Monologを使って、バッチのログを指定したテーブルに出力することができました。
テーブルカラムや、BatchMonologHandlerクラスのwtiteメソッドをいじればいろんな形で出力できそうですね。
バッチファイルが増えてきたら、ログ出力する前のLog::channel('batch');
を書くのが忘れそうっていうのが気になりますね。何かいい方法ないかな?
- 投稿日:2020-10-14T15:58:00+09:00
使おうぜ php 画像加工 Intervention\Image\Facades\Image;
とりあえず、表題の通り、phpを使って画像を加工したい。
しかし、できることが多すぎるので、よく使う機能だけをピックアップしていく。下準備
インストール方法は、省く
HogeController.phpuse Intervention\Image\Facades\Image;背景に画像を重ねる
コロまるアイコンを背景画像に重ねる。
背景画像は whitebg.png (600x381) として保存しておく。HogeController.php//コロまる アイコン $icon = 'https://pbs.twimg.com/profile_images/378800000552767745/fb8f309e621d078cfe46250d73d38047_normal.png'; //600 x 381 pixels //https://twi.ski/img/whitebg.png $bg = Image::make(public_path('/img/whitebg.png')); $icon = Image::make($icon); //bg に 対し真ん中に 重ねる $bg->insert($icon,'center'); //nakayoshi.png として保存 $bg ->save(public_path('/tmp/nakayoshi.png')); echo '<img src="/tmp/nakayoshi.png?'.time().'">';うーん♪キュート。
丸く切り抜き (マスク)
HogeContoller.php$bg = Image::make(public_path('/img/blackbg.png')); //コロまる アイコン 200 x 200 のサイズ $icon = 'https://pbs.twimg.com/profile_images/378800000552767745/fb8f309e621d078cfe46250d73d38047_200x200.png'; $icon = Image::make($icon); //背景は透過、真っ黒の円を 200 x 200 で作成 $mask = Image::make(public_path('img/mask200.png')); $icon->mask($mask,true); $bg->insert($icon, 'center'); // nakayoshi.png として保存 $bg ->save(public_path('/tmp/nakayoshi.png')); echo '<img src="/tmp/nakayoshi.png?'.time().'">';うーん!セクシー!
- 投稿日:2020-10-14T13:40:23+09:00
【Laravel】ログイン試行回数がIPと入力した認証情報の組み合わせになっている のでIPで制限する
やりたいこと
Laravel でログイン時に試行回数を設定したい
デフォルトだと同一IPからの制限になっているようでなっていませんググって参考記事とか真似して作っても
特定のIPから、入力した認証情報(emailとか、ユーザ名とか)が複数回、同じものの場合、
IPと入力した認証情報での組み合わせでロックになります。
なので、別の認証情報を入力すれば再度認証処理が走ります下記はlaravelのデフォルトのログインです(1分で5回でロック)
— 棗(なつめ) (@natsume_aurlia) October 14, 2020例えば、1分間に2回ミスるとロックの場合
1.) emailに
hoge@hoge.com
2.) emailにhoge@hoge.com
←二回同じなのでロック
3.) emailにfuga@fuga.com
←異なる認証情報なのでチェックが普通に走るこれじゃなんの意味もない...総当りし放題では...
原因
大雑把にロックの流れは、
1.キャッシュでカウントしたもので制限超えているか確認
2.認証情報でログインできる試行
3.失敗したらキャッシュでカウントLoginControllerで使ってる
trait
のAuthenticatesUsers
の
login
メソッドの中で行っていますAuthenticatesUserspublic function login(Request $request) { $this->validateLogin($request); // ここで制限超えているか確認している if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // これでキャッシュでカウントしてる!!!! $this->incrementLoginAttempts($request); //これ! return $this->sendFailedLoginResponse($request); }
incrementLoginAttempts
でカウントしています
んでこの中身ですThrottlesLoginsprotected function incrementLoginAttempts(Request $request) { $this->limiter()->hit( $this->throttleKey($request), $this->decayMinutes() * 60 ); }んで、この
hit
メソッドでキャッシュに入れたり、時間をどうのこうのしてますがここはいいのですが第一引数として渡している
$this->throttleKey($request)
でキャッシュのキーを設定しているのですがこいつが問題ですThrottlesLogins/** * Get the throttle key for the given request. * * @param \Illuminate\Http\Request $request * @return string */ protected function throttleKey(Request $request) { return Str::lower($request->input($this->username())).'|'.$request->ip(); }
$request->input($this->username()
はメールアドレスだったり、パスワードと何を入力させるのか設定しているやつ(ここではメールアドレスとして進めます)なので、メールアドレスとipを文字列でつないでキーを作っています....
なので当然メールアドレスの入力が変わればもう一度認証の試行を行います
解決策
throttleKey
をオーバーライドして、ipだけ返すようにしますLoginControllerprotected function throttleKey(Request $request) { return $request->ip(); }あとは時間と試行回数をいい感じにしておけば
入力値に関わらずIPで制限になりますLoginControllerprotected $maxAttempts = 10; protected $decayMinutes = 5;
- 投稿日:2020-10-14T13:40:23+09:00
【Laravel】ログイン試行回数がIPと入力した認証情報の組み合わせになっているのでIPで制限する
やりたいこと
Laravel でログイン時に試行回数を設定したい
デフォルトだと同一IPからの制限になっているようでなっていませんググって参考記事とか真似して作っても
特定のIPから、入力した認証情報(emailとか、ユーザ名とか)が複数回、同じものの場合、
IPと入力した認証情報での組み合わせでロックになります。
なので、別の認証情報を入力すれば再度認証処理が走ります下記はlaravelのデフォルトのログインです(1分で5回でロック)
— 棗(なつめ) (@natsume_aurlia) October 14, 2020例えば、1分間に2回ミスるとロックの場合
1.) emailに
hoge@hoge.com
2.) emailにhoge@hoge.com
←二回同じなのでロック
3.) emailにfuga@fuga.com
←異なる認証情報なのでチェックが普通に走るこれじゃなんの意味もない...総当りし放題では...
原因
大雑把にロックの流れは、
1.キャッシュでカウントしたもので制限超えているか確認
2.認証情報でログインできる試行
3.失敗したらキャッシュでカウントLoginControllerで使ってる
trait
のAuthenticatesUsers
の
login
メソッドの中で行っていますAuthenticatesUserspublic function login(Request $request) { $this->validateLogin($request); // ここで制限超えているか確認している if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // これでキャッシュでカウントしてる!!!! $this->incrementLoginAttempts($request); //これ! return $this->sendFailedLoginResponse($request); }
incrementLoginAttempts
でカウントしています
んでこの中身ですThrottlesLoginsprotected function incrementLoginAttempts(Request $request) { $this->limiter()->hit( $this->throttleKey($request), $this->decayMinutes() * 60 ); }んで、この
hit
メソッドでキャッシュに入れたり、時間をどうのこうのしてますがここはいいのですが第一引数として渡している
$this->throttleKey($request)
でキャッシュのキーを設定しているのですがこいつが問題ですThrottlesLogins/** * Get the throttle key for the given request. * * @param \Illuminate\Http\Request $request * @return string */ protected function throttleKey(Request $request) { return Str::lower($request->input($this->username())).'|'.$request->ip(); }
$request->input($this->username()
はメールアドレスだったり、パスワードと何を入力させるのか設定しているやつ(ここではメールアドレスとして進めます)なので、メールアドレスとipを文字列でつないでキーを作っています....
なので当然メールアドレスの入力が変わればもう一度認証の試行を行います
解決策
throttleKey
をオーバーライドして、ipだけ返すようにしますLoginControllerprotected function throttleKey(Request $request) { return $request->ip(); }あとは時間と試行回数をいい感じにしておけば
入力値に関わらずIPで制限になりますLoginControllerprotected $maxAttempts = 10; protected $decayMinutes = 5;
- 投稿日:2020-10-14T13:33:37+09:00
Laravel migration/Seeder/Factory作成 エラー
こんばんは〜
相変わらずエラーに苦しんでるペーペーです?先ほどFactory作成終わりました!!
まじでうれし〜〜
んで、ここからがっつりLaravelに入れるのが嬉しい!!!今回は、Factory作成で出会ったエラーちゃん達の紹介と解決方法を書いていきます!
1)
["SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint"]
[参考URL]
https://qiita.com/kitakrazy/items/6a3e1936da727dbd92b3[主な原因→解決方法]
・テーブル生成順序がおかしい → テーブルの生成順序を変えてみる
・外部キーの参照と、のっけるのが違う → 外部キーの箇所を見直す、変えてみる2)
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
[参考URL]
なし[主な原因→解決方法]
・Factory時に、重複した文字列や数値が生成されてしまった時
→ 例)'name_en' => $this->faker->word . $this->faker->randomNumber()
の様に、ランダムの数値などを結合する。3)
SQLSTATE[22003]: Numeric value out of range: 1264 Out of range value for column 'size' at row 1
[主な原因→解決方法]
・カラムのサイズをオーバーした意味。
intとかtinyintとか、decimalの定義しているサイズを超えたから
→randomFloat
若しくはrandomElement
を使用!
- 投稿日:2020-10-14T10:10:20+09:00
Laravel PHP 三項演算子の戻り値部分の記載で苦労した
目的
- Laravelのbladeファイルの記載で三項演算子を用いて「文字列+DBのデータ」を表示分岐していたところ非常に苦労したのでメモとしてまとめる
実施環境
- ハードウェア環境
項目 情報 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.8 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする Laravel バージョン 8.6.0 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする 問題箇所
下記のように記載し三項演算子の真の部分にデータを入れ込みたかった。
@inject('ContentService', 'App\Services\ContentsService') <p>{{真偽判断の式 !== 0 ? 'コンテンツの数は{{$ContentService->getContent(Auth::id())}}件です' : 'コンテンツはありません'}}</p>簡単に解説すると「真偽判断の式」が真のときのみp要素で「コンテンツの数は〇〇件です」(〇〇はDBから認証中ユーザIDを引数に取得したデータ)のように表示したかった。
中括弧が不足している旨のエラーが出て当該ページを表示する事ができなかった。
原因
- 単純明快な原因である。文字列連結がうまくできていないだけだった。
本来PHPで文字列を連結するときは下記のように
.
を使用する。//「おはようございます」と出力される echo 'おはよう' . 'ございます'エラーが出た箇所は下記の部分である。
'コンテンツの数は{{$ContentService->getContent(Auth::id())}}件です'落ち着いて見るとエラーが出るのは当たり前である。文字列部分とデータ部分の連結部分似誤りがある。正しく記載すると下記のようになる。
'コンテンツの数は' . $ContentService->getContent(Auth::id()) . '件です'上記の内容を踏まえてp要素部分を正しく記載する。
@inject('ContentService', 'App\Services\ContentsService') <p>{{真偽判断の式 !== 0 ? 'コンテンツの数は' . $ContentService->getContent(Auth::id()) . '件です' : 'コンテンツはありません'}}</p>