Laravel namespaces class not found - php

I am newbie to Laravel namespaces.
I am trying to do something like this:
namespace App\Controllers; // when I remove this line, everything works fine... I need to include this
class HomeController extends BaseController {
protected $layout = "layouts.main";
public function __construct() {
// some stuff here
}
/**
* Home page.
* #return View
*/
public function getHome() {
// Show the page
$this->layout->content = View::make('home');
}
}
But I am having this weird error,
Class HomeController does not exist
Here is some of my composer.json stuff,
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/libraries",
"app/models",
"app/database/migrations",
"app/database/seeds",
]
},
I have also executed,
composer dump-autoload
While I am routing something like this,
# Default
Route::get('/', array('as' => 'home', 'uses' => 'HomeController#getHome'));

Here's one common case where this error can occur:
Imagine you're defining a route using that class:
Route::get('/home', 'HomeController#getIndex');
The Laravel core is going to pass that string ('HomeController#getIndex') to some method(s) deep in the bowels of the routing class, parse it, instantiate HomeController, and call getIndex. Does that code include a use App\Controllers directive? Not likely, since this is something you've created. Basically, wherever that HomeController class is used (and I have no idea where it is), the PHP interpreter is not going to know where that class comes from.
The solution is to use the fully-qualified class name. That means including the full namespace in the string, like so:
Route::get('/home', '\App\Controller\HomeController#getIndex');
Now when Laravel tries to instantiate the class, it has everything it needs to find it.
I don't know for sure if this is the problem - you need to show us the code where the error occurs - but this is one possibility.

Are you typing use App\Controllers\HomeController in the file where you're trying to use it? This essentially includes it.

You don't use namespaces for Controllers in app/controllers.
HomeController extends BaseController which extends Controller in the framework.
You might want to use namespaces if you are including custom libraries into the framework. /app/libraries for example.
As long as your routes.php has some url to get to a home controller method, it should work.
Route::get('/home', 'HomeController#index');
HomeController.php:
class HomeController extends BaseController {
private $myVar;
public function __construct() {
// some stuff here
}
public function index(){
return View::make('home');
}
}

Related

Use a Zend function in every controllers

I need to be able to use a function (redirect with some parameters) from different controlers of my application.
I need to use $this->_helper->redirector($param1, $param2), and declare it just one time somewhere. Then I'll put this function in others controllers. If one day I modify the function, I don't need to modify it in each controller.
What I'm looking for is an equivalent of Symfony's services I guess.
Thanks for help :) .
What you 're asking for is called controller plugin in Laminas or Zend. You can code your own controller plugin, that you can use in every controller you want.
<?php
declare(strict_types=1);
namespace Application\Controller\Plugin;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
class YourPlugin extends AbstractPlugin
{
public function __invoke($param1, $param2)
{
// your logic here
}
}
You have nothing more to do as to mention this plugin in your module.config.php file.
'controller_plugins' => [
'aliases' => [
'doSomething' => \Application\Controler\Plugin\YourPlugin::class,
],
'factories' => [
\Application\Controller\Plugin\YourPlugin::class => \Laminas\ServiceManager\Factory\InvokableFactory::class,
]
]
If you want to use some dependencies in your controller plugin, you can write your own factory for your plugin and add that dependencies via injection.
As your new plugin is mentioned in the application config, you can call your plugin in every controller you want.
<?php
declare(strict_types=1);
namespace Application\Controller;
class YourController extends AbstractActionController
{
public function indexAction()
{
$this->doSomething('bla', 'blubb');
}
}
Please do not use traits as a solution for your issue. Laminas / Zends already ships a redirect controller plugin. Perhaps a ready to use solution is already there or you can extend the redirect controller plugin ...

How to add custom class in laravel 5.4.10

I am new in laravel.
I am writing following code in the controller method.
include_once(app_path() .'/Classes/Pgp_2fa.php');
$pgp = new Pgp_2fa();
Following errors are shown.
FatalThrowableError in AuthController.php line 146: Class
'App\Http\Controllers\Pgp_2fa' not found
You have to use the correct namespace for your class.
If you are not using any namespace, you should add a \ in front of the class to let php know that the class exists in the root namespace. Otherwise php will look in the current namespace which is App\Http\Controllers when you are in a controller.
$pgp = new \Pgp_2fa();
This is not just Laravel behavior but php in general.
When you add new classes there are couple way to use them. (I mean, load them)
If your classes has unique name and don't use namespace, then you can add backslash \ start of the class.
$class = new \Pgp_2fa;
But if you want to define them namespaces and use with same name so
many times, then you have to add these classes in composer.json. Open your
composer.json and come into "autoload" section and define class
directory in classmap
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"app/Classes", // so all classes in this directory are going to load
],
And don't forget to say composer dump-autoload after these changes and creating new classes
If you don't want to dump your composer when you add a new class,
then you may want add those classes inside of the psr-4 section in composer
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\Classes\\": "app/Classes",
}
},
you need to add namespace for your custom class
or just add slash on your class name. like :
$pgp = new \Pgp_2fa();
You can call inside the constructor like below, and you can use the
$Pgp_2fa variable in remaining function
class controllername extends Controller
{
public function __construct(Route $route,Request $request)
{
$Pgp_2fa = new \Pgp_2fa();
}
}
You can easily add your custom classes by added it to Composer's autoload array. Go to composer.json and add it to:
"autoload": {
"files": [
"app\\Classes\\Pgp_2fa.php"
]
},
Now in your app folder, under classes folder add your Pgp_2fa.php file which will have your class. You can use it anywhere you want, it should be automatically auto-load-ed.
After adding your class write command:
composer dumpautoload to refresh autoload class mapping.
For example, There is our class Common.php in a directory called Mylibs in app directory.
app/mylibs/Common.php
we need to namespace App\Mylibs;
namespace App\Mylibs;
class Common {
public function getSite() {
return 'AmirHome.com';
}
}
Now, you can access this class using the namespace within your classes just like other Laravel classes.
use App\Mylibs\Common
in Controller:
namespace App\Http\Controllers;
use App\Mylibs\Common;
class TestController extends Controller {
protected $common;
public function __construct(Common $common) {
$this->common = $common;
}
public function index() {
echo $this->common->getSite();
}
}

Getting "Class 'app\Http\Controllers\Controller' not found" in Laravel 5.1

I'm quite new to Laravel and when I am going through a tutorial when I encountered this error. This is my code in 'testController.php'.
<?php
namespace app\Http\Controllers;
use app\Http\Controllers\Controller;
class testController extends \app\Http\Controllers\Controller {
public function getAbout()
{
return view('Learning.about') ;
}
public function getHome()
{
return view('Learning.index');
}
}
And this is my 'routes.php'.
<?php
Route::get('test', [
'as' => 'test',
'uses' => 'testController#getHome',
]);
Route::get('about', [
'as' => 'about',
'uses' => 'testController#getAbout',
]);
I am getting this error:
Class 'app\Http\Controllers\Controller' not found
How can I fix this error?
Let's go through this step by step.
1. Check autoload directive on composer.json
Open composer.json file on your project root directory. Locate the the autoload section. It should be looking like this:
{
...
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
}
Make sure you have this configuration under the psr-4 option:
"App\\": "app/"
This configuration tells the composer that we want to autoload all classes inside the app directory using psr-4 convention and places it under the App namespace.
2. Update your controller
First, your controller file name should be in CamelCase style. So we have to renamed it to TestController.php. Make sure that it's saved under app/Http/Controllers directory.
Now open your TestController.php file, we have to capitalize the namespace and class name like so:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class TestController extends Controller {
public function getAbout()
{
return view('Learning.about') ;
}
public function getHome()
{
return view('Learning.index');
}
}
Note that we also turn this line:
class testController extends \app\Http\Controllers\Controller
Into:
class TestController extends Controller
Since we already import the base Controller class, we don't have to specify the fully qualified name. We imported the Controller class using the use keyword:
use App\Http\Controllers\Controller;
Save your TestController.php file.
3. Update your routes file
Now we have to update our app\Http\routes.php file. We just need to capitalize the controller name:
<?php
Route::get('test', ['uses' => 'TestController#getHome', 'as' => 'test']);
Route::get('about', ['uses' => 'TestController#getAbout', 'as' => 'about']);
4 Update your autoloader
Now the last thing to do. Open your terminal / command prompt. Go to your project directory and run the following command:
composer dump-autoload
This command will update the autoloader file (Read more here).
Now if you open up your browser and hit /test route, you should see the content from resources/views/Learning/index.blade.
Use correct namespace:
namespace App\Http\Controllers;
// Remove: use app\Http\Controllers\Controller;
class testController extends Controller {
According to my experience in Laravel projects, the namespaces starts with the capital A of App used in namespace, you should try to change your code to this:
namespace App\Http\Controllers;
class testController extends Controller { }
Also check if the controller - App\Http\Controllers\Controller lies in the same namespace as mentioned in your code.
Include this at the top of your Controller file. This fixed it for me.
namespace App\Http\Controllers;
In some cases the problem is that the framework is not able to instantiate your given controller class. This can happen for example if you are using a sub-folder under Controllers and that when you are extending the Controller.php class, you did not provide the use statement to that definition*. Other run-time errors may also cause this.
*Which is now required since your own controller is not at the root of the Controller folder anymore.

How do you include a global class in laravel

I would like to include a class for every controller to use. Here is what I tried with no luck.
In the Controller.php file, I added this line of code:
use App\Lib\RequestType;
Then in my controller UserController.php, I called a test function.
dd(RequestType::test());
But a fatal error is thrown.
Class 'App\Http\Controllers\RequestType' not found
What is laravel looking for the class in the Controllers folder. Shouldn't UserController inherit the Controller class?
Thanks in advance
If you are trying to write a static class and call it by use, then one option is to make use of autoload feature of composer, which will enable the class to be used anywhere.
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"app/Lib"
]
},
Then in any controller
use RequestType;
then
dd(RequestType::test());
Note: Function test should be like
public static function test()
There is no way to auto-magically have a class everywhere.
PHP use is not inherited by extending classes. Even Laravel's Facades have to specified.
You can store the class in the App\Http\Controllers\Controller->__contruct() to make it more easily manageable.
// App\Http\Controllers\Controller
public function __construct()
{
$this->requestType = new RequestType();
}
// App\Http\Controllers\FooController
public function __construct()
{
parent::__contruct();
}
public function index()
{
$requestType = $this->requestType;
}

Laravel 4 Nested Controllers and Routing

Is it possible to call a control that is nested within a sub folder in Laravel 4?
My Controllers are as follows
- Controllers
- admin
* AdminController.php
* HomeController.php
* BaseController.php
* ArticleController.php
Below is the code from my AdminController class:
<?php
class LoginController extends BaseController {
public function showLogin()
{
return View::make('partials.admin.login');
}
}
In my Routes.php file I am doing the following:
Route::get('/admin', 'admin.LoginController#showLogin');
But I'm getting a Class not found error. Is there anything I'm missing as I can't seem to find out how to solve this problem from the Laravel 4 documentation.
As long as you don't change the namespace of the controller you should be able to access it from the global namespace even if it is in a subfolder.
So just change:
Route::get('/admin', 'admin.LoginController#showLogin');
to:
Route::get('/admin', 'LoginController#showLogin');
The filename also needs to match the class name so change 'AdminController.php' to 'LoginController.php' or change the class name from 'LoginController' to 'AdminController'.
And make sure you do composer dump-autoload
You just need to add namespace in your AdminController.php file and change name of the class from LoginController to AdminController
AdminController.php will then be:
<?php
namespace Admin;
use BaseController;
class LoginController extends BaseController {
public function showLogin()
{
return View::make('partials.admin.login');
}
}
and change your routes.php to :
Route::get('/admin', 'admin\LoginController#showLogin');
I experienced a problem when I stored my admin controller in a subdirectory of the controllers directory app/controllers/admin
I had to add this directory to the list of autoload classmaps in my composer.json file
Then run composer dump-autoload
Adding a trailing slash to "app/controllers" in composer.json worked for me:
"autoload": {
"classmap": [
"app/commands",
"app/controllers/",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
Then run composer dump-autoload
may be its too late but one of the possible ways is to use namespaces.
here is my sample:
routes.php :
Route::group(array('prefix' => 'admin' , 'before' => 'admin' ), function()
{
Route::controller('contacts' , '\backend\ContactController');
...
}
and on top of your backend controllers add add these lines :
namespace backend;
use \view as view;
and also add these lines to your composers.json in classmap directive :
"app/controllers/backend",
"app/controllers/front",

Categories