Контролер цільового класу не існує - Laravel 8


109

Ось мій контролер:

<?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');
    }
}

Як видно на скріншоті, клас існує і знаходиться у правильному місці:

введіть тут опис зображення

Мій api.phpмаршрут:

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

Коли я потрапив у свій registerмаршрут за допомогою Поштовика, це призвело до такої помилки:

Цільовий клас [Api \ RegisterController] не існує.


Оновлення:

Завдяки відповіді я зміг це виправити. Я вирішив використовувати для цього маршруту повну назву класу, але є й інші варіанти, як описано у відповіді.

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

ласкаво просимо до SO .. ваш контролер знаходиться всередині Apiпапки.?
Камлеш Павло

Вам потрібно відновити класи, оскільки composer dump-autoloadабо у вашому RegisterControllerвідсутньому просторі імен.
ста

@KamleshPaul так
Nguyễn Việt Dũng

тоді спробуйcomposer dump-autoload
Камлеш Павло

я просто вводжу це у своєму терміналі?
Nguyễn Việt Dũng

Відповіді:


205

Ви використовуєте Laravel 8. У новій інсталяції Laravel 8 префікс простору імен не застосовується до ваших груп маршрутів, в які завантажуються ваші маршрути.

"У попередніх випусках Laravel, що RouteServiceProviderмістило $namespaceвластивість. Значення цієї властивості буде автоматично додано до префіксу до визначень маршруту контролера та викликів actionпомічника / URL::actionметоду. У Laravel 8.x ця властивість є nullза замовчуванням. Це означає, що немає автоматичної префікса простору імен зробить Laravel ". Документи Laravel 8.x - Примітки до випуску

Вам потрібно було б використовувати повне ім’я класу для своїх контролерів, коли вони посилаються на них у своїх маршрутах, коли не використовують префікс простору імен.

use App\Http\Controllers\UserController;

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

Якщо ви віддаєте перевагу старому способу:

App\Providers\RouteServiceProvider:

public function boot()
{
    ...

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

    ...
}

Зробіть це для будь-яких груп маршрутів, для яких потрібно оголошений простір імен.

$namespaceвластивість:

Хоча в примітках до випуску є згадка про $namespaceвластивість, яку потрібно встановити для вас, RouteServiceProviderі коментувати у вашій, RouteServiceProviderце не впливає на ваші маршрути. Наразі це лише для додавання префіксу простору імен для генерації URL-адрес до дій. Отже, ви можете встановити цю змінну, але вона сама по собі не додаватиме цих префіксів простору імен, вам все одно доведеться переконатися, що будете використовувати цю змінну при додаванні простору імен до груп маршрутів.

Ця інформація зараз знаходиться в Посібнику з оновлення

Документи Laravel 8.x - Посібник з оновлення - Маршрутизація

Те, що показує Посібник з оновлення, є важливою частиною того, що ви визначаєте простір імен для своїх груп маршрутів. Встановлення $namespaceзмінної само по собі допомагає лише у формуванні URL-адрес для дій.

Знову ж таки, і я не можу наголосити на цьому досить важливо, важливою частиною є встановлення простору імен для груп маршрутів, що вони просто роблять, посилаючись на змінну-член $namespaceбезпосередньо у прикладі.

Оновлення:

Якщо ви встановили нову копію Laravel 8, починаючи з версії 8.0.2, laravel/laravelви можете прокоментувати protected $namespaceзмінну-член у, RouteServiceProviderщоб повернутися до старої версії , оскільки групи маршрутів налаштовані на використання цієї змінної-члена для простору імен для груп.

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

Тільки причина Розкоментувати щоб додати префікс простору імен для контролерів , призначених маршрутів , тому що групи маршрутизації налаштовані використовувати цю змінну в якості простору імен:

...
->namespace($this->namespace)
...

2
Це справді зводило мене з розуму. Коментар над змінною $ namespace говорить: "Якщо вказано, цей простір імен автоматично застосовується до маршрутів вашого контролера." Ну це НЕ. Вам потрібно додати -> простір імен ('App \ Http \ Controllers'), як ви вказали. Їм справді слід змінити коментар у вихідному коді ...
shock_gone_wild

@shock_gone_wild, що коментар та властивість були вилучені з Постачальника приблизно 25 хвилин тому, тож у наступній версії виправлення laravel/laravelце буде втрачено
lagbox

1
Чому модифікацію змінили? Для підвищення продуктивності?
CodeGuru


1
@WesleySmith станом на 8.0.2 з laravel/laravelцього часу ви можете коментувати та використовувати, якщо хочете
lagbox

18
  • Так, у laravel 8 ця помилка трапляється ..
  • Спробувавши безліч рішень, я отримав ці ідеальні рішення
  • Просто виконайте кроки ...

СПРАВА - 1

Ми можемо змінювати файли api.phpта web.phpфайли, як показано нижче.
Поточний спосіб написання syntax- це

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

слід змінити на

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

СПРАВА - 2

  1. Спочатку перейдіть до файлу: app > Providers > RouteServiceProvider.php
  2. У цьому файлі замініть рядок
    protected $namespace = null;наprotected $namespace = 'App\Http\Controllers'; введіть тут опис зображення
  3. Потім Після додавання рядка, ->namespace($this->namespace)як показано на малюнку ..
    введіть тут опис зображення

1
Це працює для мене.
Шрікант Парді

@ShrikantPardhi Дякую. Будь ласка, проголосуйте, якщо справді ця відповідь вам допомогла :)
Рохіт Тагадія

9

у laravel-8 за замовчуванням видаліть префікс простору імен, щоб ви могли встановити старий спосіб у laravel-7, наприклад:

в RouteServiceProvider.phpдодати цю змінну

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

та bootметод оновлення

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'));
        });
}

6

laravel 8 оновив RouteServiceProvider, і це впливає на маршрут із синтаксисом рядка. Ви можете змінити його, як вище, але рекомендованим способом є використання синтаксису дії, не використання маршруту із синтаксисом рядка:

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

Необхідно змінити на:

Route::get('register', [RegisterController::class, 'register']);

5

У laravel 8 ви просто додаєте свій простір імен контролера в маршрути \ web.php

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

Або

пройдіть шлях `app \ Providers \ RouteServiceProvider.php` і видаліть коментарі

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


2

Якщо ви використовуєте laravel 8

просто скопіюйте та вставте мій код

use App\Http\Controllers\UserController;

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

1

У laravel-8 ви можете використовувати ось так

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

Дякую


1

Якщо ви хочете продовжувати використовувати оригінальну автоматичну префіксну маршрутизацію контролера, ви можете просто встановити значення властивості $ namespace у вашому RouteServiceProvider і оновити реєстрації маршрутів у методі завантаження, щоб використовувати властивість $ 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'));
    });
}


0

Якщо ви віддаєте перевагу групуванню цих маршрутів, ви можете зробити наступне:

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


0

Ви можете визначити свої маршрути в laravel 8

use App\Http\Controllers\HomeController;

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

АБО

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

Маршрут ресурсу стає

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

Це означає, що в laravel 8 за замовчуванням немає автоматичної префікса оголошень контролера.

Якщо ви хочете дотримуватися старого способу, вам потрібно додати властивість простору імен у app\Providers\RouteServiceProvider.php(Ця властивість була в попередніх версіях) і активувати в методі маршрутів. Дотримуйтесь цих вказівок нижче: введіть тут опис зображення


-1

Просто розкоментуйте під рядком від RouteServiceProvider(Якщо не існує, додайте)

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


-1

У мене сталася ця помилка

(Ілюмінація \ Contracts \ Container \ BindingResolutionException Клас цілі [App \ Http \ Controllers \ ControllerFileName] не існує.

Рішення: просто перевірте Ім'я класу, воно має точно відповідати вашому імені файлу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.