I am new to Laravel 5 and I would like someone to explain to me how exactly Laravel's namespacing works.
So I had a class named Variant in app/models/Variant.php my code looks like this
namespace App;
use Illuminate\Database\Eloquent\Model;
class Variant extends Model{
/*Some code*/
}
in my route.php I have:
use App\Variant;
/*calls Variant::all() some where in code*/
Then I get an error saying Variant is not defined. However, if I change my namespace in Variant.php from namespace App to namespace App\Models and in route.php from use App\Variant to use App\Models\Variant everything magically works.
Why is that? Does it have to do with php namespace or the classmap property in composer.json? I am very confused.
Your classes are probably loaded by composer. What's the content of it - autoloading section in particular?
I guess it's loaded by PSR-4 standard, which respects director-name\file-name pattern.
Meaning:
App\Variant is sought in app/Variant.php
App\Models\Variant is sought in app/models/Variant.php
Therefore, when you change your namespace to the one corresponding with your directory path, it works.
Related
In my new laravel app I've added two custom classes. One loads fine when I use it in the controller, but the other, which is in another folder, does not work.
The working class, which I will call Working is located in app\Classes, it has the namespace namespace App\Classes and in the controller I call it with use App\Classes\Working.
The non-working class, which I will call NonWorking is located in app\Classes\NonWorking. I've tried giving it the namespaces namespace App\Classes and namespace App\Classes\NonWorking. From the controller I've tried calling it with use App\Classes\NonWorking and use App\Classes\NonWorking\NonWorking, but I get the error Class 'App\Classes\NonWorking' not found or Class 'App\Classes\NonWorking\NonWorking' not found.
I've been able to get it to run correctly by moving the NonWorking class into the same folder as the Working class and setting the namespace as namespace App\Classes, but the NonWorking class is from another repo and should be in its own folder as it will not be the only one from another repo.
So, how do I get Laravel to understand where this class is?
Laravel uses the PSR-4 autoloading. What it means is basically your class should follow the folder structure.
So if you have classes in app/Classes, they should have the namespace App\Classes.
So the file app/Classes/Working.php will have at its top namespace App\Classes; and to import it in another file, you write in the other file use App\Classes\Working;
If you have a class inside app/Classes/SubFolder, it should have the namespace namespace App\Classes\SubFolder;
So here is a class AmazingClass in app/Classes/SubFolder/AmazingClass.php file:
// app/Classes/SubFolder/AmazingClass.php
namespace App\Classes\SubFolder;
class AmazingClass
{
//
}
Let's use AmazingClass in another class.
// Some file in another namespace
namespace App\My\Random;
use App\Classes\SubFolder\AmazingClass;
// Rest of the file
Plus: Whenever you add a new class and you can't use it, it's likely that it's not autoloaded. Run the command
composer dump-autoload
to re-autoload the classes.
to solve your issue just create your folders and classes in App folder and run command :
composer dump-autoload
and they load all classes you have created
I encountered the topic called 'namespace' in php after I started working with Laravel. While trying to understand namespace I found that to extend a class under a namespace, I need to include that class in my current page. Like the following:
directory '..\teacher\Teacher.php'
namespace Teacher;
class Teacher{
public $headTeacher='mr X';
}
to extend the calss i need to include that page as well as use the namespace
directory '..\studnet\student.php'
use \Teacher\Teacher; //use the namespace
include('../teacher/Teacher.php'); // include the page
class mathTeacher extends Teacher{
public function headTeacherName(){
echo $this->headTeacher;
}
}
$student=new mathTeacher();
$student->headTeacherName();
I am wondering how Laravel only use namespace to include classes. Like if I create a controller called 'userController'. The structure of the page is
namespace App\Http\Controllers;
class userController extends Controller{
}
They never included the php page which holds the 'controller' class. But they were able to extend it somehow. Also I can use "View" ,"Auth" just by using the use View or use Auth command. How is it done? How can I implement the same with the code I have provided? Thanks in advance.
Laravel uses composer.php for autoloading the classes. All classes in the autoload directory will be pre loaded. So you can just use the namespace and consume anywhere across the application.
Learn more about composer, composer config can be found on composer.json in your root path for the application
Initially, this code worked, but it doesn't work anymore. I don't know what is causing the issue.
The error is :
FatalErrorException in AdminController.php line 64:
Class 'App\Category' not found
AdminController code is:
<?php
namespace App\Http\Controllers;
use Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Category;
use View;
class AdminController extends Controller
{
public function article_get()
{
$categories = Category::latest()->get();
return View::make('create.article')->with('categories',$categories);
}
}
My model Category is located at App/Models/Category.php.
What I've tried:
Change from use App\Category; to use Category, to use \Category, to use App\Models\Category.
composer dump-autoload.
A few hours ago I had a working project, but now my models are not found.
Because Laravel uses PSR-4 autoloading, you need to make sure your namespaces match the real directory structure.
You say that your Category model is located at App/Models/Category.php so its namespace should be App\Models. Then, in your controllers you would use App\Models\Category.
I had also faced the same error when Models are called inside Controllers or Seeders.
The best solution is to import your Model inside the Controllers.
Add the below line at the top of your AdminController.
use App\Models\Category
This is applicable for all Classes where you try to call your models.
Do it like this and it must work:
use App\Models\Category
and make sure that the model Category is inside a folder named Models.
Your code seems fine.
May be it has an issue with namespace in Category model.
if you use this code for Category Model in your AdminController controller:
use App\Models\Category;
then your Category model itself has this namespace
namespace App\Models;
Check if your model namespace is still there or not.
Thanks
App\Models\Category
PLease Check This twoThings
1.Importing namespace App\Http\Controllers;
2,Check Controller Letter is in Upper Or LowerCase
like this
use App\models\Category----->❌❌❌
use App\Models\Category----->✅✅✅
use App\Models\Category
//check your models is capital or small letter sometimes issue like that is a big problem
I am using laravel 4.2.
Lets say there is such class:
class BShopsController extends ShopsController
To fix this, I try to use name space lets say this:
namespace app\controllers;
and then it does not find ShopsController
so I add
use \ShopsController;
Then I get error:
Class BShopsController does not exist
What namespace should I use first of all so it would not break anything?
Edit:
BShopsController and ShopsController are in folder Shops
As your files are inside the Shops folder and I believe that the Shops folder is inside the app folder you should namespace your class the following way.
<?php namespace Shops;
class BShopsController extends ShopsController{}
Similarly,
<?php namespace Shops;
class ShopsController{}
So with the help of Shhetri and this Using namespaces in Laravel 4
I did this way:
namespace App\Controllers\Shops;
class BShopsController extends ShopsController{}
Also in routes.php then need to change to this:
Route::controller('shops', 'App\Controllers\Shops\ShopsController');
And where calling action() method - also need to use namespace.
Also needed to run
composer dump-autoload -o
otherwise were errors.
Also in ShopsContrller needed to to this:
use \App\Controllers\BaseController;
Because Shops controller was in another namespace than BaseController and cannot find it. But is extending from BaseController, so need it.
a quick (maybe stupid) question.
I'm using a namespace for my controllers, like so:
namespace Members;
use DB;
use Input;
use PerformanceReport;
use Redirect;
class AdminController extends MembersController {
And as expected, I have to provide use statements for the Laravel classes I wish to use.
From what I've understood, the composer autoloader prevents this from being necessary if used correctly.
So my question being, is it possible to configure the autoloader to suit my needs, and if so, how would I go by doing this?
Your question is connected with the way PHP namespaces work, not with composer's autoloader.
If your class is in namespace Controllers; and you'd write Redirect::to('/') php would assume that the class you're referring to is in the current declared namespace (in that case Controllers/Redirect). You can either write \Redirect::to('/') or put a use Redirect statement on top like you did.
Composer's autoload just maps namespaces to their file directory (see vendor/composer/autoload_classmap.php for how it maps it).
If you want to dive more into composer's autoloading, i'd recommend read up on PSR-0 and PSR-4.