Laravel not recognizing Controller __invoke() - php

Can't debug this simple routing issue, despite going through several similar posts.
TestController is not invokable. The controller class TestController
is not invokable. Did you forget to add the __invoke method or is the
controller's method missing in your routes file?
I have played around with it as many permutations as I can find on Stack and nothing changes it. I have confirmed that simple routing, ie:
Route::get('/', function () {
return view('welcome');
});
works, but I can't get the controllers to work. I have cleared the cache and uncommented the $namespace, nothing makes a difference. In fact, the error message doesn't seem to change, which leads me to believe it's not the routing but something to do with the Controllers. But I am a newb and am not seeing it.
from web.php:
Route::get('/test', TestController::class);
TestController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller {
public function __invoke() {
return view('welcome');
}
}

This normally happens when you do not have the use statement for the FQCN of the controller.
In the routes file where you are declaring the route ensure that the use statement for the Controller namespace is added. Especially since Laravel 8.x the default namespace for controllers is not set to App\Http\Controllers unlike the earlier versions.
//routes file
use App\Http\Controllers\TestController;
Route::get('/test', TestController::class);
Just as a side note if you are using an invokable controller class to return just a view, you can use the Route::view() method instead
//Assuming that you have a resources/views/test.blade.php
Route::view('/test', 'test');

Maybe this helps someone similar to me, who overlooks a simple problem:
I wrote:
Route::post('controller/{resource}/action', \App\Http\Controllers\MyController::class, 'action')->name('controller.action');
Instead what I needed was:
Route::post('controller/{resource}/action', [\App\Http\Controllers\MyController::class, 'action'])->name('controller.action');
So basically I was missing the [] around the controller class and action params, they go together in an array - got to remember that. :)
Sorry if it is a just a tiny bit off-topic, but I searched for my problem and ended up here, therefore this just might help someone else too.

I don't know if you still need to hear this but change your
Route::get('/test', TestController::class);
into
Route::get('/test', [TestController::class, #MethodName]);
Also, call your model into the Controller.file
use App\Models\Test;

Related

PHP Laravel - Controller does not exist

I am new to PHP and Laravel. I am creating my first Laravel API where I am working with Post object.
In order to do so I use a PostController. I have created this controller using the php artisan command: php artisan make:controller PostController --api. This created a PostController class inside the app\Http\Controllers.
When I want to append this controller to the api routes using the Route::resource function I came across something strange. The course I followed told me to declare the controller like so: Route::resource('posts', 'PostController');. When testing the api php artisan route:list this gave the following error:Target class [PostController] does not exist.
Then I did some research and found an other way to declare the controller inside the api routes using:
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class);
This worked for me but I don't have any clue why the first declaration failed. I have looked inside my PostController class to see any typo's. But I couldn't find any:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
...
}
The reason for this is just like the exception says: it could not find the PostController in your declared namespace.
The reason for that highly depends on the Laravel version you are using. Laravel 8 removed the default namespacing to App\Http\Controllers, so if you are using Laravel 8 but have followed a tutorial for an earlier Laravel version, that might be the reason.
However, using the declaration using class imports is the better way to do it anyways, so I would stick with that.
Since Laravel 8, there were some changes to the automatic controller namespace prefixing.
https://laravel.com/docs/8.x/upgrade#routing
You can continue to use the original auto-prefixed controller routing, see the 4th paragraph on the upgrade documentation. But the new way is recommended.
You should tell Route::resource method the controller's namespace. As you did in your second try.
If you wanna do it with your first attempt, you can tell it the required namespace
Route::resource('posts', 'App\Http\Controllers\PostController');
You can also set the namespace in your App\Providers\RouteServiceProvider:
public function boot()
{
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace('App\Http\Controllers\Api')
->group(base_path('routes/api.php'));
});
}

Routes inside controllers with laravel?

I have been declaring all the routes for my application inside web.php , but it is now getting quite large. I find that I am losing a lot of time shifting between web.php and each controller and this is hurting productivity.
I feel like it would be better to define routes inside of the controller, perhaps ideally delegating some URL to a controller and then allowing the controller to handle the "sub routes" since this would allow me to use inheritance when I have two similar controllers with similar routes.
It is not possible given how laravel works. Every request is passed onto router to find its designated spot viz. the controller with the method. If it fails to find the route within the router, it just throws the exception. So the request never reaches any controller if the route is not found. It was possible in earlier versions on Symphony where you would configure the route in the comment of a particular controller method.
Sadly with laravel it works how it works.
But for me, I just like to have the routes in a separate file.
Alternate solution, easier way to sort all the routes.
You can move your route registration into controllers if you use static methods for this. The code below is checked in Laravel 7
In web.php
use App\Http\Controllers\MyController;
.....
MyController::registerRoutes('myprefix');
In MyController.php
(I use here additional static methods from the ancestor controller also posted below)
use Illuminate\Support\Facades\Route;
.....
class MyController extends Controller {
......
static public function registerRoutes($prefix)
{
Route::group(['prefix' => $prefix], function () {
Route::any("/foo/{$id}", self::selfRouteName("fooAction"));
Route::resource($prefix, self::selfQualifiedPath());
}
public function fooAction($id)
{
........
}
In Controller.php
class Controller extends BaseController {
....
protected static function selfAction($actionName, $parameters = [], $absolute = false)
{
return action([static::class, $actionName], $parameters, $absolute);
}
protected static function selfQualifiedPath()
{
return "\\".static::class;
}
protected static function selfRouteName($actionName)
{
//classic string syntax return "\\".static::class."#".$actionName;
// using tuple syntax for clarity
return [static::class, $actionName];
}
}
selfAction mentioned here is not related to your question, but mentioned just because it allows making correct urls for actions either by controller itself or any class using it. This approach helps making action-related activity closer to the controller and avoiding manual url-making. I even prefer making specific functions per action, so for example for fooAction
static public function fooActionUrl($id)
{
return self::selfAction('foo', ['id' => $id]);
}
Passing prefix into registerRoutes makes controller even portable in a sense, so allows inserting it into another site with a different prefix in case of conflict

Do I need to have Controller.php in all my API subversion?

I am trying to create an API directory in my Laravel project and I'm receiving the following error...
Class 'App\Http\Controllers\Controller' not found
I have tried using use App\Http\Controllers\Controller; on top of my API controllers but no luck.
My API classes are defined like...
class SyncController extends Controller {...}
class TimecardController extends Controller {...}
I'm pretty sure the error is coming from the extends Controller portion.
in App\Http\Controllers\Controller I have Controller.php. One way I have pushed past this is to duplicate the Controller.php into App\Http\Controllers\Api\v2\ and change the namespace of that controller to match where it is located (namespace App\Http\Controllers\Api\v2;)
I don't believe this is correct, as there should be a way to reference the Controller.php from the controllers in the API subdirectory.
../Controllers/Controller.php and API is a subdirectory, ../Controllers/Api/v2/SyncController.php
Any help would be much appreciated.
Thanks
-----------Edit------------
my routes for the api look like so
Route::group(['prefix' => 'api/v2'], function () {
Route::get('sync', 'Api\v2\SyncController#sync')->middleware('auth:api');
Route::post('timecard', 'Api\v2\TimecardController#create')->middleware('auth:api');
});
The Controller class cannot be found because the API controllers are not in the default Laravel controller directory. You need to add the controller class as a use statement. Then the autoloader will be able to find it.
namespace App\Http\Controllers\Api\v2;
use App\Http\Controllers\Controller;
class SyncController extends Controller {...}
And while your at it you might also want to add the auth:api middleware to the entire group. Much safer and efficient.
Route::group(['prefix' => 'api/v2', 'middleware' => 'auth:api', 'namespace' => 'Api\v2'], function () {
Route::get('sync', 'SyncController#sync');
Route::post('timecard', 'TimecardController#create');
});

UnexpectedValueException in Route.php line 639: Invalid route action: [App\Http\Controllers\PortfolioController]

Why am I getting this error. I created a PortfolioController. Then I made a route using this
Route::get('portfolio','PortfolioController');
So in my controller page I made this.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class PortfolioController extends Controller
{
//This only gets exectued when we request /portfolio/Paintings using GET
public function getPaintings()
{
return 'This RESTful controller is working!';
}
}
I get this error when typing in localhost/portfolio/paintings
From the look of your code, it looks like you're trying to setup an implicit controller route. You're close, but your route definition is a little off. You need to use controller instead of get:
Route::controller('portfolio','PortfolioController');
https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0
The following features are deprecated in 5.2 and will be removed in the 5.3 release in June 2016:
Implicit controller routes using Route::controller have been deprecated. Please use explicit route registration in your routes file. This will likely be extracted into a package.
You must declare each endpoint now.
try this
Route::get('portfolio','PortfolioController#getPaintings')
I got a similar error when there was a mistake in he file of web.php.
A correct route would like this Route::get('portfolio','YourController#yourMethod');
Use this code in routes:
Route::resource('portfolio','YourController#yourMethod');
you need to explain your function on Route.
example:
Route::methods('your-uri','YourController#YourFunction');
so you should do this:
Route::get('portfolio','PortfolioController#getPaintings');
Hope it helps
You have to consume a function of the controller instead of using the whole controller class for one request. so laravel doesn't know which of your function to use.
Try using PortfolioController#index. or Route::resource('yourroute','PortfolioController');
Try this: Route::resource('/portfolio','PortfolioController');
Hope this will work

Laravel Controller in Folder - Routing doesn't work

I am putting my Controller called "LoginController" in a folder "login".
class LoginController extends BaseController{
public $restful = true;
//log in function
public function Login(){
// load the login page
return View::make('login.login');
}
}
In the routes, I give this:
Route::get('/',array('uses'=>'login.LoginController#Login'));
Also tried
Route::get('/',array('uses'=>'login\LoginController#Login'));
Route::get('/',array('uses'=>'login\Login#login'));
None of the above seem to work, and give me Class does not exist error.
I am very dumbstruck with this error. Is the way I am accessing the controller in the "uses" correct? Do I need to do any additional things before I can get it to work?
Any help really appreciated!
All you should need is
Route::get('/',array('uses'=>'LoginController#Login'));
Composer need to register this change in routes so dump-autoload composer
php composer.phar dump-autoload
Also if you are using laravel 4, then declaring restful controllers with
public $restful = true;
no longer works.
this happens to me often, just to give a different answer that worked for me
php artisan dump-autoload
Enjoy!
Yeah i had the same issue, i got my answer from https://stackoverflow.com/a/31638718/2821049
Route::group(['namespace' => 'login'], function(
{
// Controllers Within The "App\Http\Controllers\login" Namespace
Route::get('/','LoginController#login');
});
In class you adds :
namespace App\Http\Controllers\folder;
use App\User;
use App\Http\Controllers\Controller;
and in routes you call:
Route::get("admin/login","folder\class#NameFunctionInClass");
Note: folder is the name folder class contains

Categories