Laravelで新しいプロジェクトを始めようとした時にひっかかったエラーの紹介です。次のコマンドを実行することで解決します。
php artisan compile:clear # 前のバージョンの Laravel ならば php artisan compile:clear の代わりに次のコマンドが使えます。 php artisan clear-compiled chmod 777 bootstrap/cache/
エラーの内容は題の通りで、より詳しく全文を張り付けると以下です。この時はプロジェクトルートを /work/backend にバインドした Docker を使っていました。PHPのバージョンは8.1.8、Laravelのバージョンは9.19.0でした。
today at 11:03:30[Tue Sep 13 11:03:30.270909 2022] [php:error] [pid 22] [client 192.168.144.1:56056] PHP Fatal error: Uncaught ReflectionException: Class "hash" does not exist in /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php:875 Stack trace: #0 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(875): ReflectionClass->__construct('hash') #1 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(756): Illuminate\\Container\\Container->build('hash') #2 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(860): Illuminate\\Container\\Container->resolve('hash', Array, true) #3 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(692): Illuminate\\Foundation\\Application->resolve('hash', Array) #4 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(845): Illuminate\\Container\\Container->make('hash', Array) #5 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(1419): Illuminate\\Foundation\\Application->make('hash') #6 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php(79): Illuminate\\Container\\Container->offsetGet('hash') #7 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php(38): Illuminate\\Auth\\AuthManager->createEloquentProvider(Array) #8 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(121): Illuminate\\Auth\\AuthManager->createUserProvider('users') #9 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(92): Illuminate\\Auth\\AuthManager->createSessionDriver('web', Array) #10 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(66): Illuminate\\Auth\\AuthManager->resolve('web') #11 /work/backend/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): Illuminate\\Auth\\AuthManager->guard('web') #12 /work/backend/app/Exceptions/Handler.php(87): Illuminate\\Support\\Facades\\Facade::__callStatic('guard', Array) #13 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(222): App\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(UnexpectedValueException)) #14 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(199): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->renderHttpResponse(Object(UnexpectedValueException)) #15 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(235): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleException(Object(UnexpectedValueException)) #16 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(259): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleShutdown() #17 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}() #18 {main} Next Illuminate\\Contracts\\Container\\BindingResolutionException: Target class [hash] does not exist. in /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php:877 Stack trace: #0 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(756): Illuminate\\Container\\Container->build('hash') #1 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(860): Illuminate\\Container\\Container->resolve('hash', Array, true) #2 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(692): Illuminate\\Foundation\\Application->resolve('hash', Array) #3 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(845): Illuminate\\Container\\Container->make('hash', Array) #4 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(1419): Illuminate\\Foundation\\Application->make('hash') #5 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php(79): Illuminate\\Container\\Container->offsetGet('hash') #6 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php(38): Illuminate\\Auth\\AuthManager->createEloquentProvider(Array) #7 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(121): Illuminate\\Auth\\AuthManager->createUserProvider('users') #8 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(92): Illuminate\\Auth\\AuthManager->createSessionDriver('web', Array) #9 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(66): Illuminate\\Auth\\AuthManager->resolve('web') #10 /work/backend/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): Illuminate\\Auth\\AuthManager->guard('web') #11 /work/backend/app/Exceptions/Handler.php(87): Illuminate\\Support\\Facades\\Facade::__callStatic('guard', Array) #12 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(222): App\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(UnexpectedValueException)) #13 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(199): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->renderHttpResponse(Object(UnexpectedValueException)) #14 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(235): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleException(Object(UnexpectedValueException)) #15 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(259): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleShutdown() #16 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}() #17 {main} thrown in /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 877
このエラーの内容ですが、端的にいうと Laravel のフレームワーク部分でサービスコンテナの使用に失敗しています。日本語ドキュメントでは以下のページが詳しいです。
サービスコンテナ 9.x Laravel
ファサード 9.x Laravel#ファサードクラスリファレンス
このファサードクラスリファレンス内にあるサービスコンテナ結合キーの hash の解決に失敗しています。スタックトレース内のコードを追うと次の部分が発端と言えます。自分のソースコードの元になったボイラープレートにあらかじめ認証によるルーティング防止があったのでそのあたりで引っかかった感じです。
// #6 /work/backend/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php(79): Illuminate\\Container\\Container->offsetGet('hash') // @see https://github.com/laravel/framework/blob/a155ccdafa229cbd0fac0033a98a24119064f87a/src/Illuminate/Auth/CreatesUserProviders.php#L79 /** * Create an instance of the Eloquent user provider. * * @param array $config * @return \Illuminate\Auth\EloquentUserProvider */ protected function createEloquentProvider($config) { return new EloquentUserProvider($this->app['hash'], $config['model']); }
スタックトレースとLaravelの仕組みからエラーが起きている場所と直接的な原因はわかりました。これの解決の失敗の原因を深堀して解消する必要があります。
このエラーは Laravel のサービスコンテナ結合キーから適切な対象を引き出せないため起きています。そして、この引き出しに使う辞書は Laravel が生成したコードの中にあります。この生成したコードを初期化するコマンドが次です。
php artisan compile:clear # 前のバージョンの Laravel ならば代わりに次のコマンドが使えます。 php artisan clear-compiled
このコマンドすら実行できない状態の場合、/bootstrap/cache/packages.php と /bootstrap/cache/services.php を直接削除します。おそらくこれで同じ結果を得られるはずです。
加えて適切な /bootstrap/cache 以下に Laravel がファイルを生成できる様に権限を設定します。例えば次です。
chmod 777 bootstrap/cache/
どこでもどのユーザーでも使える様にするために↑のコマンドにしましたが、プロジェクトの所有者とウェブサーバーを動かすユーザーを同一にする対応もできます。
これで解決するはずです。