Laravel 8

Como corrigir o erro “Target class [Controller] does not exist” no Laravel 8

O framework Laravel 8 trás uma série de novos recursos, melhorias em funções já conhecidas e algumas alterações estruturais. Uma destas mudanças foi a remoção do “namespacing” de rota padrão, desta maneira tem gerado certa confusão e o erro “Target class [Controller] does not exist”.

Esta mudança é compatível com versões anteriores, o que significa que projetos mais antigos que usavam o Laravel 7.x podem facilmente migrar para o Laravel 8.x, sem alterar nada pois a estrutura básica de seus componentes é mantida, porém novos projetos criados no Laravel 8 devem levar isso em consideração.

O problema decorrente desta mudança em seus aplicativos Laravel 8 recém-criados, ao tentar carregar as rotas depara-se com uma exceção como:

Target class [MeuController] does not exist.

O problema não está relacionado necessariamente a um erro de código, mas a um ajuste necessário, ainda mais levando em conta que 99,9% dos tutoriais a respeito Laravel (ao menos até a versão 7) não dependia deste ajuste de namespace padrão para a configuração de rotas.

A Mudança

Até a versão 7 do framework Laravel, o arquivo RouteServiceProvider.php tinha o seguinte código na configuração da propriedade $namespace:

<?php

    protected $namespace = 'App\Http\Controllers';

...

    public function boot()
    {
        ...
        Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

Na leitura deste código: por padrão o Laravel configurava o Service para carregar as rotas em routes/web.php, usando o middleware web e o namespace App\Http\Controllers. Isso, por sua vez, significa que sempre que você declarar uma rota usando a sintaxe de string, o Laravel irá procurar pela classe controladora, considerando como “raiz” a pasta App\Http\Controllers. Como no exemplo da configuração de uma rota:

Route::get('artigos', '[email protected]');

Qual mudança ocorreu no Laravel 8? Simples porém impactante, a variável $namespace não é mais configurada por padrão no RouteServiceProvider, e a declaração/configuração do carregamento de rotas alterou para:

Route::middleware('web')
    ->group(base_path('routes/web.php'));

Isto significa que o Laravel está procurando por rotas dentro do seu arquivo web.php, como sempre. Também está aplicando o middleware da web, como sempre. Porém, observe que ele não está mais usando o namespace anterior.

Isso significa que a partir do Laravel 8, quando você declara suas rotas usando a sintaxe de string, o framework Laravel não vai procurar seu controlador dentro de App\Http\Controllers. E caso você utilize esta sintaxe, o erro de exceção Target class [Controller] does not exist será lançado.

Controller na mensagem acima será o nome do seu controlador na sua mensagem de erro

Como corrigir este erro?

Primeiro vamos entender o problema gerado: o Laravel não sabe onde procurar seu controlador, então é necessário “informar” a ele onde a classe está.

Existem 3 maneiras de fazer isso:

  1. Adicionando o $namespace novamente na configuração para que você possa continuar usando as rotas como fazia no Laravel 7.x e versões anteriores
  2. Usar o namespace completo em seus arquivos de rota ao usar a sintaxe de string
  3. Usar a sintaxe de ação – action syntax(recomendado)

Adicionando a configuração do $namespace

Isso é bastante simples. Acesse o arquivo RoutesServiceProvider.php, primeiramente insira a linha a seguir no início da classe (ou retire o comentário se ela existir assim):

protected $namespace = 'App\Http\Controllers';

Em seguida adicione a chamada ao método namespace para cada configuração de rota na função boot. O resultado deve se parecer com o código a seguir:

    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace) // <- esta linha deve ser inserida
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)  // <- esta linha deve ser inserida
                ->group(base_path('routes/web.php'));

Desta maneira voltamos a configurar as rotas do Laravel para que ele considere o App\Http|Controllers a base para sua descoberta.

Usando o namespace completo

Esta alteração envolve alterar todas as suas declarações de rota. Apesar de trabalhoso é simples: prefixe os nomes dos seus controladores com seus namespaces. No exemplo a seguir para uma classe ArtigosController dentro da pasta app/Http/Controllers:

// note como adicionamos o namespace completo antes do nome da classe
Route::get('artigos', 'App\Http\Controllers\[email protected]');

Usando a sintaxe de ação – action syntax

Esta é a alternativa mais recentemente recomendada por ser menos suscetível a erros de digitação e, em minha experiência, oferece melhor suporte ao IDE, pois informamos explicitamente ao código qual classe usar.

Portanto, ao invés de usarmos a sintaxe de string usual, podemos usar a sintaxe de ação em que especificamos a classe e o método a serem usados em uma matriz como parâmetro do método da rota sendo configurado:

// sintaxe de string
Route::get('artigos', 'App\Http\Controllers\[email protected]');

// sintaxe ação. 
use App\Http\Controllers\ArtigosController;

Route::get('artigos', [ArtigosController::class, 'getAll']);

Note que para utilizar a sintaxe de ação é necessário importar a classe no arquivo de rotas, usando use App\Http\Controllers\ArtigosController, isto será necessário para todas as classes de controladores a serem utilizadas.

O atributo das classes PHP, ::class trará o namespace completo, juntamente com o nome da classe, desta maneira o Laravel saberá onde encontrar o controlador e irá executar o método passado na segunda da posição do array, em nosso exemplo o método getAll.

Considerações finais

Agora seu aplicativo deve funcionando corretamente. Caso ainda encontre problemas, sinta-se à vontade para pedir ajuda. Você pode me encontrar no Twitter como @nunomazer.

Se você adicionou o namespace manualmente, especificou-o completo em suas rotas, ou seguiu com a sintaxe de ação, o que você acabou de fazer foi dizer ao Laravel como encontrar seus controladores na estrutura da aplicação.

Mais sobre Laravel

  • PHP Composer, erro: Invalid version string

    Trabalhando recentemente com o PHP Composer em um projeto que tem como base o framework Laravel, me deparei com o erro: Invalid version string. Mais precisamente ao realizar a tentativa de instalar um pacote Laravel que me permite utilizar modelos com a estratégia lógica do Eloquent para acessar bancos de dados MongoDB. O nome do […]

  • Componentes de arquitetura do Framework Laravel

    Todo framework de desenvolvimento entrega uma arquitetura padronizada com o objetivo de organizar o trabalho das equipes de projetos de software com boas práticas de programação. Com o framework Laravel isto não é diferentes, e neste artigo você terá uma visão geral dos componentes que compõem sua arquitetura. Note que para cada componente do Laravel […]

  • Framework Laravel – O que é

    Laravel é um framework de aplicação, com base em um projeto Open Source – Código Fonte Aberto, destinado ao desenvolvimento de sistemas para web, com sintaxe expressiva e elegante. Ele é desenvolvido na linguagem PHP, sendo de fácil adoção e aprendizado. Sua primeira versão pública foi um beta lançado em meados de 2009. Sua estrutura […]

  • Instalar aplicação Laravel em subdiretório com CPanel

    Se você trabalha com o framework PHP Laravel, sabe que instalar sua aplicação em um diretório padrão de uma conta VPS ou servidor compartilhado, sem alterações, irá obrigá-lo a executar o sistema deixando exposto o diretório raiz da aplicação, pois precisará acessar o mesmo pelo subdiretório /public. Por exemplo: http://meudominio.com.br/public Em caso de acesso ao […]

  • Como corrigir o erro “Target class [Controller] does not exist” no Laravel 8

    O framework Laravel 8 trás uma série de novos recursos, melhorias em funções já conhecidas e algumas alterações estruturais. Uma destas mudanças foi a remoção do “namespacing” de rota padrão, desta maneira tem gerado certa confusão e o erro “Target class [Controller] does not exist”. Esta mudança é compatível com versões anteriores, o que significa […]

  • Laravel 8

    O Laravel 8 foi lançado e inclui muitos novos recursos, incluindo o Laravel Jetstream, um diretório exclusivo para models (modelos), classes de fábrica de modelos, squashing de migração, melhorias nas limitações de quotas (rate-limit), helplers para testes de datas e time, componentes dinâmicos de blade e muitos outros recursos. Antes de continuarmos o artigo com […]

Mantenha-se atualizado

Não esqueça de me seguir no Twitter e assinar o Canal Mazer.dev no Youtube para receber atualizações de novos artigos, vídeo aulas e cursos gratuitos em desenvolvimento e engenharia de software.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Um pensamento em “Como corrigir o erro “Target class [Controller] does not exist” no Laravel 8”

%d blogueiros gostam disto: