コマンドライン上でのphp実行時に追加php.iniを読み込ませる
さくらレンタルサーバーではwebからのアクセス時に /home/[username]/www/php.ini が読み込まれるようになっています。
しかし、デプロイやバッチ処理などコマンドラインからの実行では読み込まれないため、手動でロードさせる必要があるようです。
https://www.php.net/manual/ja/features.commandline.options.php
php -c /home/[username]/www/php.ini filename.php
Laravelのキャッシュ生成・削除系コマンドの違い一覧
キャッシュ生成や削除コマンドはいくつか用意されているがコマンドによっては複数種のキャッシュを操作したりしなかったりするのでまとめておく。
| command | config | route | view | event | cache | compiled | description |
|---|---|---|---|---|---|---|---|
| config:cache | C | C | Create a cache file for faster configuration loading | ||||
| config:clear | D | C | Remove the configuration cache file | ||||
| route:cache | C | C | Create a route cache file for faster route registration | ||||
| route:clear | D | C | Remove the route cache file | ||||
| view:cache | C | C | Compile all of the application's Blade templates | ||||
| view:clear | D | C | Clear all compiled view files | ||||
| event:cache | C | C | Discover and cache the application's events and listeners | ||||
| event:clear | D | C | Clear all cached events and listeners | ||||
| cache:clear | D | C | Flush the application cache | ||||
| cache:forget | D*1 | C | Remove an item from the cache | ||||
| optimize | C | C | C | Cache the framework bootstrap files | |||
| optimize:clear | D | D | D | D | D | Remove the cached bootstrap files | |
| clear-compiled | D | Remove the compiled class file |
C: キャッシュ作成、 D: キャッシュ削除、 *1 指定されたキーのキャッシュのみを削除
基本的に xxx:cache ⇔ xxx:clear が対になっており、作成コマンドは削除→作成の順番で実行される。
optimize のみ操作が非対称な点に注意。
compiled キャッシュはLaravelアクセス時に自動生成されるため、compiledキャッシュ削除コマンド以外では生成される。
デプロイ時は以下のコマンド実行で一通りのキャッシュを葬り去ることができる。
php artisan optimize:clear php artisan optimize php artisan view:cache php artisan event:cache // ジョブ機能を利用している場合のみ php artisan queue:flush
各キャッシュの生成されるファイル一覧
config
/bootstrap/cache/config.php に各configがマージされた配列として保存される。
route
/bootstrap/cache/route.php に各routeがマージされ、シリアライズされたデータとして保存される。
view:cache
\storage\framework\views ディレクトリ内に各bladeファイルがphpにパースされたものが保存される。
また、ファイル名はsha1でハッシュ化される。
https://github.com/laravel/framework/blob/master/src/Illuminate/View/Compilers/Compiler.php#L51
event:cache
/bootstrap/cache/event.php に各イベントがマージされた配列として保存される。
compiled
依存パッケージのパス、サービスプロバイダが配列として保存される。
/bootstrap/cache/packages.php , /bootstrap/cache/services.php
Ruleクラスからドットを含むキー名のattributeを取得する
まずカスタムルールクラスでは任意のバリデーションエラーメッセージを返せます。
class ImageRule implements Rule
{
public function passes($attribute, $value)
{
// do something
}
public function message()
{
return 'The :attribute must be image';
}
}
この時、resources/lang/{locale}/validation.phpの共通エラーメッセージを引用して共通化する場合、少々手間がかかります。 方針としてはメッセージ生成にattribute名が必要なため、passesメソッド内でメッセージを生成し、messageメソッドではそれを返すようにします。
class ImageRule implements Rule
{
private $message;
public function passes($attribute, $value)
{
// do something
$this->message = 'message';
}
public function message()
{
return $this->message;
}
}
// image: 'message.'
次に翻訳されたメッセージを取得します。今回は既存のimageルールのメッセージ形式を利用します。
class ImageRule implements Rule
{
private $message;
public function passes($attribute, $value)
{
// do something
$this->message = __('validation.image');
}
public function message()
{
return $this->message;
}
}
// image: 'The :attribute must be an image.'
最後にattribute名も同様に取得します。 この時、キー名がネストしていない(ドットを含まない)場合はそのままキー名で取得できます。
// validation.php 'attributes' => [ 'user.image' => 'Image', ], class ImageRule implements Rule { private $message; public function passes($attribute, $value) { // do something $this->message = __('validation.image', ['attribute' => __('validation.attributes.'.$attribute)]); } public function message() { return $this->message; } } // image: 'The Image must be an image.'
キー名がネストしている場合(user.imageなど)一旦翻訳データ一覧を取得する必要があります。
$attribues['user.image'] ではなく、$attribues['user']['image'] へアクセスしてしまうドット記法の弊害です。
// validation.php 'attributes' => [ 'user.image' => 'Avatar Image', ], class ImageRule implements Rule { private $message; public function passes($attribute, $value) { // do something // validation.attributes配列のuser.imageキーの値を取得。 $tranlated_attribute = app('translator')->get('validation.attributes')[$attribute]; $this->message = __('validation.image', ['attribute' => $tranlated_attribute]); } public function message() { return $this->message; } } // user.image: 'The Avatar Image must be an image.'
'validation.attributes."user.image", 'validation.attributes.[user.image] などでもダメでした。
エラーをメールで送信する
LaravelではエラーログをファイルやSlackに設定一つで出力できる。 しかし管理者宛などにメールに出力する設定は用意されていないので作成してみた。 monologがいろいろ用意してくれているのでそれを継承するだけで実装可能。
- 手順
- メール送信用のハンドラを作成する
- config/logging.php でメール送信用のチャンネルを追加する。
メール送信用のハンドラを作成する
適当なディレクトリに Monolog\Handler\MailHandler を継承したハンドラを作成する。
送信メソッドのみ定義すればOK。
https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/MailHandler.php#L49
namespace App\Handlers;
use Monolog\Handler\MailHandler as BaseHandler;
class MailHandler extends BaseHandler
{
protected function send($content, array $records): void
{
// 送信処理
}
}
config/logging.php でメール送信用のチャンネルを追加する。
先ほど作成したハンドラを使用するように設定。 通常のファイル出力とエラー時のみメール送信するように設定してみた。
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'mail'],
'ignore_exceptions' => false,
],
'mail' => [
'driver' => 'monolog',
'level' => 'error',
'handler' => MailHandler::class,
],
ログインに条件を追加する
ログイン可能なユーザーを制限するときにどこいじると楽かの試行錯誤と結果。
やりたいこと
- 有効なユーザかつ有効な所属企業の場合ログイン可能
- Authの標準機能PWリセットが上記ユーザーの場合のみ利用可能
試したこと
- ログインコントローラーを改造する ⇒ PWリセットは別途対応が必要に(めんどい)
- ログイン可能ユーザーのEloquentモデルを別に定義する ⇒ Auth全般が適用範囲になるので楽
Docker for Windows で "driver failed programming external connectivity on endpoint" になるのを解決する
悲しみ
Docker for Windows を入れるためにわざわざ Windows10 を Home から Pro に変えたのに konozama.
docker-compose up -d Creating network "app_name_default" with the default driver Creating app_name_db_1 ... error ERROR: for app_name_db_1 Cannot start service db: driver failed programming external connectivity on endpoint app_name_db_1 (xxxx): Error starting userland proxy: mkdir /port/tcp:0.0.0.0:13360:tcp:172.21.0.2:3306: input/output error ERROR: for db Cannot start service db: driver failed programming external connectivity on endpoint app_name_db_1 (xxxx): Error starting userland proxy: mkdir /port/tcp:0.0.0.0:13360:tcp:172.21.0.2:3306: input/output error ERROR: Encountered errors while bringing up the project.
解決策
その場対応
win起動時に自動で立ち上がるdockerを再起動すれば直ります。
タスクバーで座礁しているクジラ型コンテナ船を Restart して大海原へ戻してあげればいいです。

恒久的対応
Windowsご自慢の素敵機能「高速スタートアップ」を無効にすることで解消できます。
参考記事:https://github.com/docker/for-win/issues/1038#issuecomment-373231436
起動が遅くなる可能性がありますが、M.2のSSDを使っているので体感では分からず。
続きを読むHello World
今までは Qiita に記事を書載せていました。
が、Qiitaの圧倒的ドメインパワーでびみょい記事が伸びたりしてしまうので、びみょい記事はこちらに書くことに。
