鶏口牛後な日々

心の赴くまま、やりたいことを仕事に。

php Laravel エラー集 [WIP] (個人的備忘録)

ArgumentCountError: Too few arguments to function <ファンクション名> 0 passed and exactly 1 expected

これは、「引数、つまりfunction()のこのカッコ内に書くものが、足りませんよ〜」というエラー。 function(引数A, 引数B)と書いているのに、引数Aしか渡していなかったら、「もう一個引数くれないとfunctionを動作させることができないよぉ〜」と言ってきているということですね。 phpユニットで、テストが通らず毎回このエラーが出たのですが、オチは、@dataProviderのアノテーションを書く時、大文字のPと書くべきところを小文字で書いていた、ということでした。

BadMethodCallException: Call to undefined method <メソッド名>

おなじみ。だいぶ慣れてきました。 こちらは、「こんなメソッド知らないよ〜」というエラーですね。 別クラスに書かれているメソッドであれば、'use'してあげる必要があるかもしれません。 また、スペルミス、ということもままあります。

Error: Call to a member function <ファンクション名> on null

ファンクションが呼ぼうとしている引数がnullでした、というエラーです。 $<変数名>->toArray() としていた時にこのエラーが出た時は、 toArray()が変形しようとしている、$変数に何も入っていなかった、というのがオチでした。

Error: Call to a member function toArray() on array

上のやつと似てますね。 今回は、toArray()(オブジェクトを配列にする)という関数なのに、toArray()を作用させようとしているものがすでにArrayだぜ、というエラーのようでした。 (追記:要確認)

Error: Call to a member function array_only() on array

$this->user->toArray()->array_only(['<変数名1>', '<変数名2>']); みたいな書き方をしたら出ました。 そもそも、Laravelのヘルパ関数array_only()の使い方は、 $array = array_only($array, ['変数名1', '変数名2']) みたいに書くべきなので、書き方が間違った時に出るエラーなのかな (エラーの中身がまだよくわかっていない、検証中)

ErrorException: Undefined variable: <変数名>

これは言わずと知れた、何かのメソッド等で使おうとしている変数が、それ以前に定義されていません、というエラーです。

Undefined Offset

これは、配列で存在しない位置のインデックスを参照した時に発生します。 例えば、要素が4つしかないのに、5つ目を出力させようとした時など。

Cannot declare class <クラス名>, because the name is already in use

これは、あまり調べても大して明快な回答を書いているページがないあたり、とっても基本的なんだろうなと思うのですが、 namespaceの綴りが間違っているということが多いようです。 私も、それでした。最後のsがなかった、とか。

Non-static method <クラス名>:<メソッド名> should not be called statically

staticというプロパティが付いているメソッドは、他のプログラムから、インスタンスを生成せずに呼び出せます。 そのためには呼び出したいクラスのファイルで、 public static function () { } とstaticプロパティをつけてあげないといけません。 このstaticが付いていないメソッドを、静的に(=インスタンスを生成せずに)呼び出そうとすると、「なによ、staticが付いてないじゃないのヨォ」と文句が飛ぶわけです。

Allowed memory size of 134217728 bytes exhausted

これ、検索すると、phpが使えるメモリ量を設定で変える(ini_set('memory_limit', '-1');)というソリューションが結構書かれています。 でも、騙されちゃいけないらしいです。 私も、かろうじて、「え、ほんとに? そんなメモリすぐ大きくしちゃっていいの??」と疑問を持って調べてみたところ、やっぱり「違うよ!! みんなそれ間違い!」と言っているサイトやStackoverflowの記事を見つけました。 ソースのどこかにバグがあって、それのためにphpが使える全てのメモリを費やすほどまでやっちゃっているということらしいのです。 つまり、ここでメモリの量を増やしちゃダメで、やるべきかバグ探しなのでした。 案の定、探してみたら、値を受け取れなかった配列についてforeachしちゃってました。

ReflectionException Class db.connection does not exist

ちょっとそもそもの意味は理解していないのですが、昨日まで普通に接続できていたところがいきなりこのエラー。 というとき、composerなどのライブラリ管理をupdateしてみると直りました。お試しあれ。

MethodNotAllowedHttpException

これ、めちゃめちゃ苦しめられました。 stackoverflow見てもいい答えが全然なくて。この質問で、質問者の方が自己解決した結果を書いてくれていて、それで分かりました。 validationがfailするときに、必ず出て、でもvalidationのせいじゃありませんでした。 validationでfailすると、前画面へリダイレクトしてくれますが、そのとき、Route::getの記述がないとどこに戻るかわからないらしい。 自動で色々やってくれるから、そんな構造になっていることが分かりませんでした。 Route::getの記述をルートに追加したら、validationがちゃんと帰るようになりました。

NotFoundHttpException

こちらもルーティング関係のミスだと思い、ずっとルートの書き方を直したりしていましたが、 結論としては、呼び出した先のコントローラのメソッド内のスペルミスでした・・・ とはいえ、上は例外で、基本は、ルーティングのミスのようです。

別で、 - (ハイフン)は使えない、というのに引っかかって時間をロスしたこともありました。 APIの設計では、よく - (ハイフン)を使え、 _ (アンダースコア)は使うな、と書いてあるのを目にします。 しかし、Laravelの公式ドキュメントにもあるように、Laravelのルーティングでは、 - (ハイフン)は使えず、 _ (アンダースコア)を代わりに使うらしい。 目を皿のようにしてみても、何がおかしいのか分からない! という人は、このミスに陥っているかも。

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table shops add constraint shops_mall_id_foreign foreign key (mall_id) references id (malls))

これは、「php artisan migrate」した時にでるエラーです。 shopsのmall_idというキーが、mallsというテーブルを参照しようとしているのにありません! というエラーですね。 マイグレーションは、作成順に実行していくようです。 つまり、親テーブルから順番に作らず、子から先に作ってしまうと、参照しようとしているテーブルが、マイグレーション実行のその時にはないので、怒られるという流れです。 マイグレーションは、親テーブルから先に作っていく! というのが鉄則ですね。

別の時は、参照しようとしている親と子のキーの、型が同じでないので、外部キー制約を付与できません、という意味だったこともあります。 例えば、よくある話として、親テーブルのidを参照する場合がありますよね。この時、idは、incremenst()で追加することが多いです。 その場合、子テーブルのキーの型としては、integerで、かつ、 unsigned とする必要があります。 なぜなら、increments()する場合、自動でunsigned(マイナスの数値を取らない)という条件が付加されているからです。 おかしいな、と思ったら、生成されたテーブルの型を確かめて、想定どおり同じ型で作られているかを確認すると良さそうです。

親テーブルの方(referd table): shops
$table->increment('id');

だとすると

子テーブルの方(refering table): products
$table->integer('shop_id')->unsigned();
$table->foreign('shop_id')->references('id')->on('shops');

とする必要があります。この、 integerunsigned がミソということですね。

SQLSTATE[HY000]: General error: 1553 Cannot drop index 'shops_products_id_foreign': needed in a foreign key constraint"

こちらは、 php artisan migrate:rollback しようとしたら出ました。 なにかというと、foreign key制約を drop しようとしたらできなかったぜ、っていうエラーのようです。 原因は、migrationの down メソッドに、foreign keyをdropする記述( dropForeign ) を書き忘れていたことでした。

    public function down()
    {
        Schema::table('exhibits', function (Blueprint $table) {
            $table->dropForeign('exhibits_shop_id_foreign');
            $table->dropColumn('shop_id');
        });
    }

この時、 dropColumn する前に、 dropForeign する、という順番を守っていないと、もうカラムがないからdropForeignできないよ、というエラーが出続けます。 (そんなポカミスし続けるの私くらいか・・・)

drop tableしてしまった!

migrationは、一個一個順番にcreateしたりalterしたりしてくれる機能なので、mysqlに直接アクセスしてテーブルをdropとかしてしまうと、混乱しちゃうみたいです。 なので、dropしてしまったtableを手動でcreateするか、下記で全部揚げ直しかどっちかですね。 create table試しましたが、なんかいろいろと細かく変わっていたりとかしてうまくいかず、結局こちらで全取っ替えしました。

php artisan migrate:fresh

多分これだけで、全部落として作り直してくれると思うけれど、もしかしたらテーブルは手動で消してからかもしれない。

以上。