РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
694 of 1392 menu

BindingResolutionException

Исключение BindingResolutionException выбрасывается контейнером сервисов Laravel, когда он не может создать экземпляр класса или разрешить зависимость. Это происходит, если класс не зарегистрирован в контейнере, не имеет необходимых привязок, или если параметры конструктора не могут быть автоматически разрешены. Данное исключение часто возникает при работе с внедрением зависимостей, фасадами и автоматическим разрешением классов.

Причины возникновения

Основные причины появления BindingResolutionException:

1. Класс не зарегистрирован в контейнере. Если вы пытаетесь внедрить класс, который не был связан с интерфейсом или не зарегистрирован явно, контейнер может не найти его.

2. Параметры конструктора не могут быть разрешены. Если конструктор класса принимает параметры, которые не являются объектами (например, скалярные значения), контейнер не сможет автоматически подставить их значения.

3. Ошибка в фасаде. При использовании фасада, если соответствующий класс не связан с контейнером, возникает исключение.

4. Проблемы с автозагрузкой. Если класс не может быть загружен автозагрузчиком Composer, контейнер также не сможет его найти.

Синтаксис

Исключение выбрасывается автоматически контейнером при попытке разрешить несуществующий или неправильно зарегистрированный класс.

<?php use Illuminate\Contracts\Container\BindingResolutionException; // Исключение может быть перехвачено вручную try { app()->make(NonExistentClass::class); } catch (BindingResolutionException $e) { echo $e->getMessage(); } ?>

Результат выполнения кода:

"Target class [NonExistentClass] does not exist."

Пример

Рассмотрим ситуацию, когда класс зависит от скалярного параметра, который не может быть разрешён автоматически:

<?php namespace App\Services; class UserService { protected $apiKey; public function __construct($apiKey) { $this->apiKey = $apiKey; } public function getUsers() { return ['user 1', 'user 2']; } } ?>

Если попытаться разрешить этот класс через контейнер без предварительной привязки, возникнет исключение:

<?php use App\Services\UserService; use Illuminate\Support\Facades\Route; Route::get('/users', function () { $service = app()->make(UserService::class); return $service->getUsers(); }); ?>

Результат выполнения кода:

"Unresolvable dependency resolving [Parameter #0 [ <required> $apiKey ]] in class App\Services\UserService"

Пример

Для решения проблемы с примитивными параметрами можно зарегистрировать привязку в сервис-провайдере:

<?php namespace App\Providers; use App\Services\UserService; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(UserService::class, function ($app) { return new UserService('abc123'); }); } } ?>

Теперь контейнер сможет разрешить зависимость:

<?php use App\Services\UserService; use Illuminate\Support\Facades\Route; Route::get('/users', function () { $service = app()->make(UserService::class); $users = $service->getUsers(); foreach ($users as $user) { echo $user . "\n"; } }); ?>

Результат выполнения кода:

"user 1" "user 2"

Пример

Рассмотрим случай с интерфейсом, для которого не зарегистрирована реализация:

<?php namespace App\Contracts; interface RepositoryInterface { public function all(); } ?>

Попытка разрешить интерфейс без привязки вызовет исключение:

<?php namespace App\Http\Controllers; use App\Contracts\RepositoryInterface; class UserController extends Controller { protected $repository; public function __construct(RepositoryInterface $repository) { $this->repository = $repository; } } ?>

Если попытаться обратиться к этому контроллеру, возникнет исключение:

<?php use App\Http\Controllers\UserController; use Illuminate\Support\Facades\Route; Route::get('/users', [UserController::class, 'index']); ?>

Результат выполнения кода:

"Target [App\Contracts\RepositoryInterface] is not instantiable while building [App\Http\Controllers\UserController]."

Пример

Исправим ситуацию, зарегистрировав конкретную реализацию для интерфейса:

<?php namespace App\Providers; use App\Contracts\RepositoryInterface; use App\Repositories\UserRepository; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind( RepositoryInterface::class, UserRepository::class ); } } ?>

Теперь интерфейс успешно разрешится, так как контейнер знает, какую реализацию использовать.

Смотрите также

  • класс Handler,
    который обрабатывает все исключения в приложении
  • исключение ModelNotFoundException,
    которое возникает при поиске несуществующей модели
  • исключение HttpException,
    которое выбрасывается при HTTP-ошибках
  • исключение ValidationException,
    которое возникает при ошибках валидации данных
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить