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

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

Related

Laravel 8 issue with controller inside subfolder

I have laravel 8 project and I am facing issue with controller which is in subfolder.
I have DashboardController located in /app/Http/Controllers/Dashboard. In my web.php I have:
use App\Http\Controllers\Dashboard\DashboardController;
Route::get('dashboard', [DashboardController::class, 'dashboardView']);
DashboardController has this namespace:
namespace App\Http\Controllers\Dashboard;
I have tried uncomment $namespace variable in RouteServiceProvider.php. Also I have added:
->namespace($this->namespace);
in boot() method. But with no luck. I got this error:
Class 'App\Http\Controllers\Dashboard\Controller' not found"
When I have DashboardController in laravel controller folder, everything works well. Also interesting is LoginController. It is in Auth subfolder (Controllers/Auth) and this controller works from subfolder.
Reason why I want to move controller into subfolder(s) is better organisation of files.
Is anybody here, who can help me figure out this issue? Thank you very much in advance.
In that class file you are referencing Controller; most likely extends Controller on the class definition. There is no class named Controller in that namespace you have declared, App\Http\Controllers\Dashboard. You are most likely trying to reference App\Http\Controllers\Controller which means you will need a use statement for that or referencing it by its FQCN, Fully Qualified Class Name.

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

how laravel autoload classes and use them without initiate it?

I am trying to deep dive laravel concept. In the very first step i got stuck. Loading different classes and use them.
In the laravel routing (where you can register web routes for your application), there is no any use keyword used for using class and initiate Route class in web.php
Route::get('/home', 'HomeController#index')->name('home');
how Route::get run without using any class?
And when we go more deep using model class
namespace hosam\Http\Controllers\Auth;
use hosam\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Auth;
use Illuminate\Support\Facades\DB;
and we use Auth in aur code like this.
Auth::login($user);
from using use keyword does php load auth class in our code where we are using Use Auth?
All the route files under routes folder are loaded automatically by laravel. routes/web.php and laravel/api.php are assigned to middleware web and api respectively.
All the classes and namespaces in laravel are loaded from the composer autoloader.
These files are mapped in the RouteServiceProvider class under Provider folder. So that class use Route facade. As the web.php and api.php is not called directly so there is no need to initiate the class in the particiular file
//RouteServiceProvider.php
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Routing
You can also make your Helper folder with HelperClass and run can be run from any where
make folder in app > Helpers folder.
make helper class Helpers.php
where you can write all your function like
function write_yourfunction(){
// your code
// return something
}
to load every where you can use service provider. Edit app > Providers > AppServiceProvider.php
public function register()
{
foreach (glob(app_path() . '/Helpers/*.php') as $filename) {
require_once($filename);
}
}
Now you can call write_yourfunction() from everywhere

How to use a trait as a route controller method in laravel?

Target [App\Http\Controllers\Traits\FileUploadTrait] is not instantiable.
I get this error when trying to send a file upload to this route:
<?php
namespace App\Http\Controllers\Traits;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
trait FileUploadTrait
{
/**
* File upload trait used in controllers to upload files
*/
public function saveFiles(Request $request)
{
//some file upload code
}
}
in my route:
Route::post('upload/files', ['uses' => 'Traits\FileUploadTrait#saveFiles', 'as' => 'media.upload']);
how to use a trait as a route controller#method?
You can't use a Trait as controller since Trait's are not classes, but actually they "are a mechanism for code reuse in single inheritance languages such as PHP." (See php docs).
A trait is not instantiable, this means that under the hood, Laravel can't do
$controller = new FileUploadTrait() to use it.
To use a trait, you must include it on some class, for example:
class MyController {
use FileUploadTrait;
}
Then you define your routes to use that class that you define.
traits arent callable... which means :) you cannot call them :Dlol, sorry - couldnt help myself... anyway try with something like this :)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
class MahController extends Controller {
use App\Http\Controllers\Traits\FileUploadTrait;
}
Traits cannot be 'instantiated', you add them on objects.

Laravel 5.3 Array on routes

I'm new to Laravel and still trying to get myself familiar with it's syntax since I originally programmed in Java.
I came across this syntax in one of the tutorials I'm watching.
Route::get('/', [
'uses'=>'ProductController#getIndex',
'as' => 'product.index'
]);
I understand that the ProductController is the controller class, #getIndex is the method (if you will) residing in the ProductController class.
What are uses, as and product.index? I see that they are pairs of keys and values.
Can I modify the uses and as to whatever name I want?
I don't see product.index anywhere in the folder. At first I thought it was a view.
These are the files.
web.php
Route::get('/', [
'uses'=>'ProductController#getIndex',
'as' => 'product.index'
]);
ProductController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class ProductController extends Controller
{
public function getIndex(){
return view('shop.index');
}
}
Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['imagePath','title','description','price'];
}
Please explain.
I'd appreciate any useful explanation to this.
Thank you.
What you've said is correct. The route is using the ProductController and asking for the getIndex() method. Yup you're free to name the routes how you'd like to, and your methods also.
As the the alias, 'as' is the route name see here (Named Routes).
'product.index'
is the route name.
So you could do...
Route::get('/', 'ProductController#getIndex')->name('product.index');
This would then allow you to use this route for say a redirection.
return redirect()->route('product.index');
It's totally optional to name a route.
Hope that helps!

Categories