El controlador de clase de destino no existe - Laravel 8

109

Aquí está mi controlador:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class RegisterController extends Controller
{
    public function register(Request $request)
    {
        dd('aa');
    }
}

Como se ve en la captura de pantalla, la clase existe y está en el lugar correcto:

ingrese la descripción de la imagen aquí

Mi api.phpruta:

Route::get('register', 'Api\RegisterController@register');

Cuando llegué a mi registerruta usando Postman, me dio el siguiente error:

La clase de destino [Api \ RegisterController] no existe.


Actualizar:

Gracias a la respuesta, pude arreglarlo. Decidí usar el nombre de clase completamente calificado para esta ruta, pero hay otras opciones como se describe en la respuesta.

Route::get('register', 'App\Http\Controllers\Api\RegisterController@register');
Nguyễn Việt Dũng
fuente
bienvenido a SO .. ¿Está su controlador dentro de la Apicarpeta?
Kamlesh Paul
Necesita regenerar las clases como composer dump-autoloado en su RegisterControllerespacio de nombres faltante.
sta
@KamleshPaul sí
Nguyễn Việt Dũng
luego intentecomposer dump-autoload
Kamlesh Paul
¿Lo escribo en mi terminal?
Nguyễn Việt Dũng

Respuestas:

205

Estás usando Laravel 8. En una nueva instalación de Laravel 8, no se aplica ningún prefijo de espacio de nombres a tus grupos de rutas en los que se cargan tus rutas.

"En versiones anteriores de Laravel, RouteServiceProvidercontenía una $namespacepropiedad. El valor de esta propiedad se agregaría automáticamente a las definiciones de ruta del controlador y a las llamadas al método actionauxiliar URL::action. En Laravel 8.x, esta propiedad es nullpor defecto. Esto significa que no hay prefijos automáticos de espacio de nombres será realizado por Laravel ". Documentos de Laravel 8.x - Notas de la versión

Debería utilizar el nombre de clase totalmente calificado para sus controladores cuando se refiera a ellos en sus rutas cuando no utilice el prefijo del espacio de nombres.

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
// or
Route::get('/users', 'App\Http\Controllers\UserController@index');

Si prefiere la forma antigua:

App\Providers\RouteServiceProvider:

public function boot()
{
    ...

    Route::prefix('api')
        ->middleware('api')
        ->namespace('App\Http\Controllers') // <---------
        ->group(base_path('routes/api.php'));

    ...
}

Haga esto para cualquier grupo de rutas para el que desee un espacio de nombres declarado.

La $namespacepropiedad:

Aunque se menciona una $namespacepropiedad que se establecerá en usted RouteServiceProvideren las notas de la versión y se comentará en su, RouteServiceProvideresto no tiene ningún efecto en sus rutas. Actualmente solo sirve para agregar un prefijo de espacio de nombres para generar URL a las acciones. Por lo tanto, puede configurar esta variable, pero por sí sola no agregará estos prefijos de espacio de nombres, aún tendrá que asegurarse de usar esta variable al agregar el espacio de nombres a los grupos de rutas.

Esta información ahora está en la Guía de actualización

Documentos de Laravel 8.x - Guía de actualización - Enrutamiento

Con lo que muestra la Guía de actualización, lo importante es que está definiendo un espacio de nombres en sus grupos de rutas. Establecer la $namespacevariable por sí sola solo ayuda a generar URL para acciones.

Nuevamente, y no puedo enfatizar esto lo suficiente, la parte importante es configurar el espacio de nombres para los grupos de rutas, lo que simplemente hacen al hacer referencia a la variable miembro $namespacedirectamente en el ejemplo.

Actualizar:

Si ha instalado una copia nueva de Laravel 8 desde la versión 8.0.2 laravel/laravel, puede descomentar la protected $namespacevariable miembro en el RouteServiceProviderpara volver a la forma anterior, ya que los grupos de rutas están configurados para usar esta variable miembro para el espacio de nombres de los grupos.

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

La única razón para descomentar que agregaría el prefijo del espacio de nombres a los controladores asignados a las rutas es porque los grupos de rutas están configurados para usar esta variable como espacio de nombres:

...
->namespace($this->namespace)
...
lagbox
fuente
2
Esto realmente me estaba volviendo loco. El comentario sobre la variable de espacio de nombres $ dice: "Si se especifica, este espacio de nombres se aplica automáticamente a las rutas de su controlador". Bueno, NO lo es. Debe agregar -> espacio de nombres ('App \ Http \ Controllers') como señaló. Realmente deberían cambiar el comentario en el código fuente ...
shock_gone_wild
@shock_gone_wild ese comentario y propiedad se eliminaron del proveedor hace unos 25 minutos, por lo que en la próxima versión de parche laravel/laraveldesaparecerá
lagbox
1
¿Por qué se cambió la modificación? ¿Para mejorar el rendimiento?
CodeGuru
la versión en video de esta respuesta (5 minutos) youtu.be/MfE1tnMG6fE
Wibisono Indrawan
1
@WesleySmith a partir de 8.0.2 laravel/laravelestá ahí para que descomente y use si lo desea
lagbox
18
  • Sí, en laravel 8 se produce este error.
  • Después de probar muchas soluciones, obtuve la solución perfecta.
  • Solo sigue los pasos ...

CASO 1

Podemos cambiar en api.phpy en web.phparchivos como a continuación ..
La actual forma de escritura syntaxes

Route::get('login', 'LoginController@login');

debería cambiarse a

Route::get('login', [LoginController::class, 'login']);

CASO - 2

  1. Primero ve al archivo: app > Providers > RouteServiceProvider.php
  2. En ese archivo reemplace la línea
    protected $namespace = null;conprotected $namespace = 'App\Http\Controllers'; ingrese la descripción de la imagen aquí
  3. Luego, después de agregar la línea ->namespace($this->namespace)como se muestra en la imagen.
    ingrese la descripción de la imagen aquí
Rohit Tagadiya
fuente
1
Me está funcionando.
Shrikant Pardhi
@ShrikantPardhi Gracias. Vota si realmente esta respuesta te ayudó :)
Rohit Tagadiya
9

en laravel-8 por defecto, elimine el prefijo del espacio de nombres para que pueda configurar la forma antigua en laravel-7 como:

en RouteServiceProvider.phpagregar esta variable

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

y bootmétodo de actualización

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

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

            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));
        });
}
Jignesh Joisar
fuente
6

laravel 8 actualizó RouteServiceProvider y afecta la ruta con la sintaxis de cadena.Puede cambiarla como se indicó anteriormente, pero la forma recomendada es usar la sintaxis de acción sin usar la ruta con la sintaxis de cadena:

Route::get('register', 'Api\RegisterController@register');

Debería cambiarse a:

Route::get('register', [RegisterController::class, 'register']);
Mirshod Mirjonov
fuente
5

En laravel 8, simplemente agrega el espacio de nombres de tu controlador en routes \ web.php

use App\Http\Controllers\InvoiceController; // InvoiceController is controller name Route::get('invoice',[InvoiceController::class, 'index']);

O

vaya a la ruta `app \ Providers \ RouteServiceProvider.php` y elimine los comentarios

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

Mobarak Hossen
fuente
2

Si está utilizando laravel 8

solo copia y pega mi código

use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);
Tijani
fuente
1

En laravel-8 puedes usar así

 Route::group(['namespace'=>'App\Http\Controllers', 'prefix'=>'admin',
 'as'=>'admin.','middleware'=>['auth:sanctum', 'verified']], function()
{
    Route::resource('/dashboard', 'DashboardController')->only([
        'index'
    ]);
});

Gracias

hariom nagar
fuente
1

Si desea continuar usando el enrutamiento del controlador con prefijo automático original, simplemente puede establecer el valor de la propiedad $ namespace dentro de su RouteServiceProvider y actualizar los registros de ruta dentro del método de arranque para usar la propiedad $ namespace:

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

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

            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));
    });
}
Ivan Fretes
fuente
0

Para la solución, simplemente descomente la línea 29:

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

en el archivo ' app \ Providers \ RouteServiceProvider.php '.

solo descomenta la línea 29

Bruno García
fuente
0

En caso de que prefieras agrupar estas rutas, puedes hacer lo siguiente:

Route::group(['namespace' => 'App\Http\Controllers\Api'], function () {
    Route::resource('user', 'UserController');
    Route::resource('book', 'BookController');
});

Saroj Shrestha
fuente
0

La forma de definir tus rutas en laravel 8 es

use App\Http\Controllers\HomeController;

// Using PHP callable syntax...
Route::get('/', [HomeController::class, 'index']);

O

// Using string syntax...
Route::get('/', 'App\Http\Controllers\HomeController@index');

Una ruta de recursos se convierte

Route::resource('/', HomeController::class);

Esto significa que en laravel 8, no hay un prefijo de declaración de controlador automático por defecto.

Si desea seguir con la forma anterior, debe agregar una propiedad de espacio de nombres en app\Providers\RouteServiceProvider.php(Esta propiedad estaba presente en versiones anteriores) y activar en el método de rutas. Siga las instrucciones de esta imagen a continuación: ingrese la descripción de la imagen aquí

Haronur
fuente
-1

Simplemente elimine el comentario debajo de la línea de RouteServiceProvider(si no existe, agregue)

protected $namespace = 'App\\Http\\Controllers';
Jatin Kaklotar
fuente
-1

En Laravel 8, la forma en que se especifican las rutas ha cambiado:

Route::resource('homes', HomeController::class)->names('home.index');
Ikram Ghalib
fuente
-1

Tuve este error

(Illuminate \ Contracts \ Container \ BindingResolutionException La clase de destino [App \ Http \ Controllers \ ControllerFileName] no existe.

Solución: simplemente verifique el Nombre de su clase, debe ser exactamente el mismo que su nombre de archivo.

Noor Alalem
fuente