メモ > 技術 > フレームワーク: Laravel > トラブル対応
トラブル対応
■マイグレーションを実行できない
以下のエラーが表示される場合、
データベースの文字コードがutf8mb4の場合にVARCHARの最大文字数が191文字に制限されるため
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes (SQL: alter table `users` add unique `
users_email_unique`(`email`))
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes
/test/app/Providers/AppServiceProvider.php の宣言に
use Illuminate\Support\Facades\Schema;
を追加し、さらに boot() 内に以下を追加するとマイグレーションできるようになる
(なお、191を例えば255にすると「長すぎる」といってエラーになる)
Schema::defaultStringLength(191);
個別のマイグレーションを編集して対応はできるが、
他にもLaravelがマイグレーションファイルを作成することがあるため、この設定を入れておく方が無難
MySQL - Laravel 5.4 デフォルトで設定されているマイグレーションファイルを実行するとSQLエラーが出る(63441)
https://teratail.com/questions/63441
MySQLのインデックスサイズに767byteまでしかつかえない問題と対策 - ハマログ
https://blog.e2info.co.jp/2017/04/17/mysql%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%...
■意図したファイルを読み込めない・参照できない
ファイルを参照できないときに試すこと
以下のように直接読み込めば参照できるが、正しい方法ではない
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
require_once $baseDir . '/database/seeds/ArticlesTableSeeder.php';
$this->call(ArticlesTableSeeder::class);
このような場合、
・use を指定しているか
・/config/app.php でパスは設定されているか
・/config/ 内の他のファイルにもパス指定がある
・/app/Http/Kernel.php でパスは設定されているか
・/app/Providers/AppServiceProvider.php でパスは設定されているか
・/app/Providers/ 内の他のファイルにもパス指定がある
などを確認する。また
composer dump-autoload
でオートロードの設定を更新できる
php artisan config:clear
で設定(.env や config/*.php のファイル)のキャッシュを削除できる
artisan view:clear
でビューのキャッシュを削除できる
artisan route:clear
でルートのキャッシュを削除できる
php artisan cache:clear
でその他のキャッシュを削除できる(ElastiCacheなどの内容だと思われる)
Laravel キャッシュクリア系コマンドなど - Qiita
https://qiita.com/Ping/items/10ada8d069e13d729701
Laravelで名前空間を指定してオートロードされなかったら見る場所。 - Qiita
http://qiita.com/niiyz/items/5b83ef5255a1ec64d9d6
[Laravel]デプロイ時の最適化 - Qiita
http://qiita.com/qiita-kurara/items/d37dbc5b67e6b6dfbe1d
Laravel キャッシュクリア系コマンドなど - Qiita
https://qiita.com/Ping/items/10ada8d069e13d729701
■「APP_ENV=production」にすると動作しない
$ vi .env
APP_ENV=production
と設定するとエラーになって動作しない。「It is unsafe to run Dusk in production.」というエラーになっている
Laravel5.4から5.5へ更新する - Qiita
https://qiita.com/sutara79/items/c07882be23a53c498482
「解決策: discoverの対象からDuskを外す」
$ vi composer.json
"extra": {
"laravel": {
"dont-discover": [
"laravel/dusk" … 追加
]
}
},
$ composer install
これで大丈夫…のはずだが、試した時は以下の警告も表示された。(composer install は実行できる)
Package phpoffice/phpexcel is abandoned, you should avoid using it. Use phpoffice/phpspreadsheet instead.
調べてみると
composer.json 内に「excel」の文字は無いが composer.lock 内にはある
という状態だった
composer.lock 内に「phpoffice/phpexcel」の記述があるので、composer.lock 自体を削除してから再度実行
$ composer install
これで大丈夫だった
それでも駄目なら、composer.lock を削除して composer install --no-dev を実行すると完了できた
[Laravel] プロダクション環境にはLaravel Duskをインストールしない - 端くれプログラマの備忘録
http://www.84kure.com/blog/2017/09/17/laravel-%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%82%B7%E3%83%A7...
■「APP_ENV=production」にするとマイグレーションとシーダーを直接実行できない
$ vi .env
APP_ENV=production
と設定すると、マイグレーションやシーダーの実行時に確認が表示される
これ自体は有用な仕組みだが、シェルスクリプトなどから実行したい場合には煩わしい
以下のように「--force」を付ければ、確認なしにマイグレーションやシーダーを実行できる
$ php artisan migrate --force
$ php artisan db:seed --force
■「PHP Fatal error: Maximum function nesting level of '512' reached, aborting!」というエラーになる
以下の現象ではあるが、上限を上げても解決しない
無限ループになってしまっているみたい
PHP - Fatal error: Maximum function nesting level of '100' reached, aborting!(169)|teratail
https://teratail.com/questions/169
複数のクラスから同じオブジェクトを注入しようとしたとき、このような現象になることがあるみたい?
Laravelのコンストラクタインジェクションの仕様らしい?
部分的にコンストラクタインジェクションではなくメソッドインジェクションを使うか、
AppServiceProviderに登録するなどで回避できるみたい
どういった方法がベストなのかは要検討
LaravelのDIの挙動を勘違いしていてドハマリした件 - Qiita
https://qiita.com/ak-ymst/items/00e7d3cee16ba6d3e710
■FormRequestのカスタムバリデーション属性名を attributes() で指定しても認識されない
app\Providers\ValidatorServiceProvider.php
ValidatorServiceProvider の boot() の処理内容を修正する
Laravel自体の不具合かも?でも修正前の状態でも属性名が反映されている案件がある。要調査
public function boot()
{
\Validator::resolver(function ($translator, $data, $rules, $messages) {
return new RuleValidator($translator, $data, $rules, $messages);
});
}
↓
public function boot()
{
\Validator::resolver(function ($translator, $data, $rules, $messages, $attributes) {
return new RuleValidator($translator, $data, $rules, $messages, $attributes);
});
}
Laravel の Validation を正しく拡張する - Qiita
https://qiita.com/moobay9/items/f1cdd3c8f995fdcf0963
■コンストラクタでユーザ情報を取得できない
Laravel5.3で変更された仕様
5.3からは middleware を挟むことで取得できる
コンストラクタでAuth::user()を取得する方法 - Qiita
https://qiita.com/capybara1229/items/98d5179f9fa599011de0
Laravel 5.3 コントローラのコンストラクタの重要な変更 - ララジャパン
https://www.larajapan.com/2016/09/24/laravel-5-3%e3%80%80%e3%82%b3%e3%83%b3%e3%83%88%e3%83%ad%e3%83%...
■composer install でエラーになる
開発環境でライブラリを追加し、composer.json と composer.lock が更新されたものを検収環境に反映
…のようなときに発生した
$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for facebook/webdriver 1.6.0 -> satisfiable by facebook/webdriver[1.6.0].
- facebook/webdriver 1.6.0 requires ext-zip * -> the requested PHP extension zip is missing from your system.
Problem 2
- facebook/webdriver 1.6.0 requires ext-zip * -> the requested PHP extension zip is missing from your system.
- laravel/dusk v2.0.14 requires facebook/webdriver ~1.0 -> satisfiable by facebook/webdriver[1.6.0].
- Installation request for laravel/dusk v2.0.14 -> satisfiable by laravel/dusk[v2.0.14].
ext-zip が無いと言われるが、zipコマンドはインストールされている
composer.lock を削除して再実行すると完了できた
他環境用にバージョンが固定されてしまっていたからかも?
composer.lock の削除は良い方法では無いと思われるので、
以下などを参考にしつつベストな管理方法を考えたい
にわかエンジニアの備忘録: composer.lockはGit管理すべき話
https://sho-memo01.blogspot.com/2019/08/composerlockgit.html
作業ブランチではcomposer.lockの変更を最小化してください - Qiita
https://qiita.com/tanakahisateru/items/ff4118ffd6a404bceb64
■メールを送信すると、本文が Attachment.html という添付ファイルになる
HTMLメールを softbank.ne.jp のアドレスで受信すると、本文が添付ファイルになってしまう
iPhoneでHTMLメールのメルマガが読めない場合 - リザーブストックの使い方
http://reservestock.hatenablog.jp/entry/2015/10/17/050502
メール送信時、view() ではなく text() にする
その際、本文内の改行タグや実体参照も不要になるので注意
Laravel 5.3 でメールを送る - Qiita
https://qiita.com/apricoton/items/d93b358bb8960b803b19
手軽に Mail::send で送るなら、第一引数を調整すればテキストメールになる
[Laravel] Mailableクラスを作らずに、Mail::sendでサクッとメールを送信する - YoheiM .NET
https://www.yoheim.net/blog.php?q=20181207
以下の場合はHTMLメールになる
Mail::send('emails.test', [ 'test' => 'テストメール' ], function ($message) {
$message
->from('from@example.com')
->to('to@example.com')
->subject('テストメール');
});
以下の場合はテキストメールになる(Mail::send の第一引数のみ変更している)
Mail::send(['text' => 'emails.test'], [ 'test' => 'テストメール' ], function ($message) {
$message
->from('from@example.com')
->to('to@example.com')
->subject('テストメール');
});
ただしSendGridを使用している場合で、一括送信メールを特定の宛先のみに届いたように見せかけるために
return $this->text('emails.remind')
->to($this->tos)
->subject('【食品ロスダイアリー】この1 週間 食品ロスはありませんでしたか?')
->with([
'body' => $this->body,
'email' => ':email',
])
->sendgrid([
'personalizations' => $tos,
]);
と sendgrid() を使用すると、本文内にimgタグが埋め込まれてしまう
これによって、Gmailなどで確認するとHTMLメール扱いになってしまう問題がある
対処法は要検証
■データベースから取得した数値が文字列として扱われる
PHP+PDOでMySQLからデータを取得した際、数値型が文字列型として扱われてしまう
よって「===」などで比較を行うと意図した結果にならないことがある
PDOでフェッチした数値型カラムの値が文字列で取得されるのでなんとかしようと頑張った。 - erio_nk://memo
http://d.hatena.ne.jp/erio_nk/20120621/1340267044
Laravelの場合、Attribute Casting により型を厳密に扱うことができるらしい
[Laravel5][Eloquent] Attribute Castingによりデータ型を厳密に取り扱う|Laravel|PHP|開発ブログ|株式会社Nextat(ネクスタット)
https://nextat.co.jp/staff/archives/140
Laravel 5.5 Pivot Casting - Laravel News
https://laravel-news.com/laravel-5-5-pivot-casting
Laravel 5 でのセキュリティ対策 (PHP) | ラボラジアン
https://laboradian.com/sec-laravel5/
■ブラウザを閉じてもセッションが終了されない
Laravelの初期設定がそのようになっている
app/config/session.php で expire_on_close を false にすればいい
Laravel セッションクッキーの有効期間をブラウザを閉じるまでにする - Qiita
https://qiita.com/shin1x1/items/af68541d0c1bbb4c66df
■.env の値に「#」を使用できない
Symfony3.txt の「トラブル」を参照
(「#」や「$」が含まれている場合の挙動が怪しい)