Как забиндить две реализации интерфейса для гостя и авторизованного пользователя соответственно?

Для забиндивания двух различных реализаций интерфейса в Laravel для гостя и авторизованного пользователя мы можем использовать механизм зависимостей и контейнер внедрения зависимостей (Dependency Injection Container).

1. Создайте интерфейс:

namespace AppInterfaces;

interface UserServiceInterface
{
    public function getInfo();
}

2. Создайте первую реализацию интерфейса для гостей:

namespace AppServices;

use AppInterfacesUserServiceInterface;

class GuestService implements UserServiceInterface
{
    public function getInfo()
    {
        return 'Вы вошли как гость';
    }
}

3. Создайте вторую реализацию интерфейса для авторизованных пользователей:

namespace AppServices;

use AppInterfacesUserServiceInterface;

class AuthenticatedService implements UserServiceInterface
{
    public function getInfo()
    {
        return 'Вы вошли как авторизованный пользователь';
    }
}

4. В файле AppProvidersAppServiceProvider.php добавьте следующий код:

use AppInterfacesUserServiceInterface;
use AppServicesGuestService;
use AppServicesAuthenticatedService;

public function register()
{
    $this->app->bind(UserServiceInterface::class, function ($app) {
        if (auth()->check()) {
            return new AuthenticatedService();
        } else {
            return new GuestService();
        }
    });
}

5. Теперь вы можете использовать интерфейс UserServiceInterface в вашем коде и Laravel будет автоматически определять, какую реализацию использовать, в зависимости от того, авторизован ли пользователь или нет.

namespace AppHttpControllers;

use AppInterfacesUserServiceInterface;

class UserController extends Controller
{
    protected $userService;

    public function __construct(UserServiceInterface $userService)
    {
        $this->userService = $userService;
    }

    public function getInfo()
    {
        return $this->userService->getInfo();
    }
}

Теперь, когда метод getInfo вызывается в контроллере, Laravel автоматически будет использовать правильную реализацию зависимости в зависимости от статуса авторизованности пользователя. Если пользователь аутентифицирован, будет возвращена реализация AuthenticatedService, если нет - GuestService.