I am starting out with Laravel 5 and as first order of business I want to move all my models into a folder called Models.
But how can I access those without specifying the namespace like in the following?:
...
class UserRolesTableSeeder extends Seeder {
public function run()
{
DB::table('user_roles')->delete();
App\Models\UserRoles::create(['name' => 'CREATE_USER']);
}
}
Go into your composer.json and add at the end of "autoload": "classmap" this line "app/models". This way you are telling laravel to autoload those clases. After that, run a composer update and it should work.
You can also create a service provider to access models without namespaces.
To create a service provider, here is what you have to do :
1) Create a file in your models directory and name it ModelsServiceProvider.php
2) Inside of it write this code
<?php
namespace App\Models;
use Illuminate\Support\ServiceProvider;
class ModelsServiceProvider extends ServiceProvider {
public function register()
{
$this->app->booting(function()
{
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('UserRoles', 'App\Models\UserRoles');
});
}
3) Go into app/config/app.php and under providers array add this line 'App\Models\ModelsServiceProvider'
You can also add directly your aliases for classes under the aliases array inside app/config/app.php.
Alternatively, you can just load your models into the global namespace like you were doing before! It's a bit scary to go against the docs but so far we haven't had any issues with it.
To make sure your models are still loaded, you just need to add the reference to your composer.json:
(assumes your namespace is App\Models)
"autoload": {
"classmap": [
...
"app/Models/"
],
...
"": [
"app/Models/"
]
be sure to run composer dump-autoload
Related
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();
}
}
I am using Laravel 5.5. I have added a custom directory inside App folder in my workspace. So, the folder structure is:
Inside App\Bishwa\Transformers there are two PHP files:
Transformer.php
LessonTransformer.php
Those files look like follows:
Transformer.php
<?php
namespace Bishwa;
abstract class Transformer {
public function transformCollection(array $items){
return array_map([$this, 'transform'], $items);
}
public abstract function transform($item);
}
LessonTransformer.php
<?php
namespace Bishwa;
class LessonTransformer extends Transformer {
public function transform($lesson){
return [
'title' => $lesson['title'],
'body' => $lesson['body'],
'active' => (boolean)$lesson['some_bool']
];
}
}
Then Inside LessonsController.php I have the following:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use App\Lesson;
use Bishwa\LessonTransformer;
class LessonsController extends Controller
{
protected $lessonTransformer;
function __construct(LessonTransformer $lessonTransformer){
dd('ok');
}
While running action of the controller, It gave me an error message saying:
Reflection Exception: Class Bishwa\LessonTransformer does not exist
I have tried composer dump-autoload, restarting the server again but none of them helped. Am I doing wrong while Namespacing or What?
Change your namespace of the files in your custom directory to App\Bishwa.
Well thanks to Jerodev and Jack. Since, both of them were write I decided to write myself a combined solution to this problem.
1st Solution:
In case of custom namespaces and custom classes I have to include the path to classname in Composer.json file in the following portion:
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"app/Bishwa/Transformers"
],
"psr-4": {
"App\\": "app/"
}
2nd Solution:
Changing NameSpace of my files to custom directory App\Bishwa .
Namespace of transformer.php and LessonTransformer.php now becomes:
namespace App\Bishwa\Transformers;
While using in LessonsController:
use App\Bishwa\Transformers\LessonTransformer;
Once again, big thanks to Jerodev and Jack. Its my silly mistake, that I couldn't figure that out.
I am just start working with Laravel, want to create a custom class and want to call this class in every controller. For this, I create a Customer class in app/Library/ folder.
When I tried to autoload this library via composer, json it's giving an error:
Could not scan for classes inside "App/Library/Customer" which does not appear to be a file nor a folder.
How can we use autoload class in controllers?
Customer.php
<?php
namespace App\Library;
use App\Model\User;
class Customer
{
public function login($user_name,$password){
$data = User::where('email', $user_name)
->where('password', $password)
->first();
return $data->id';
}
}
Autoload section of Composer.json
{
"autoload": {
"classmap": [
"database",
"app/Library/Customer"
],
"psr-4": {
"App\\": "app/"
},
"files" : [
"app/Helper/helper.php"
]
}
}
I think you're not understanding what the composer autoload is there for. You use this to include libraries and their dependencies, not really for classes you've created in your app.
What you're better off doing is when you create the controller add in the class you want to use eg:
<?php
use App\Library\Customer;
You will need to put this in every controller.
You should remove it from the classmap group and just add the proper namespace and class. You can see all the psr-4 standards here: http://www.php-fig.org/psr/psr-4/
Lets say you have a folder structure like this:
app
-> Library
-> Customer.php // namespace App\Library; class Customer{}
-> Model
-> User.php // namespace App\Model; class User{}
And all the files should autoload as long as you use the proper namespace and class names.
By the way you should use the Auth facade instead: https://laravel.com/docs/5.4/authentication
There is no need to classmap as already psr-4 autoloading is in place. You've to understand how it works. then you can simply import your classes using use keyword, like this
<?php
use App\Library\Customer;
For more information read PSR-4: Autoloader and take this Tutorial
I want to keep my seeder files separate. for example UsersTableSeeder.php , PostsTableSeeder.php and then call them in main seeder file (DatabaseSeeder.php) :
Example:
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(PostsTableSeeder::class);
}
}
usersTableSeeder.php :
<?php namespace App\Seeds;
use Illuminate\Database\Seeder;
use App\User;
class UserTableSeeder extends Seeder {
public function run()
{
//DB::table('users')->delete();
// user1
User::create(array(
'name' => 'ahmad',
'email' => 'ahmad#ahmad.com',
'password' => 'ahmad'
));
}
}
my UsersTableSeeder.php and PostsTableSeeder.php files are in the same
directory that DatabaseSeeder.php is.
should I use psr-4 autoloading ? how?
Composer.json configuration
composer.json has a autoload key to configure additional autoload paths.
You can give it a try:
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
}
Example from my composer.json
Remove the namespace line from your seeder classes. They are found by the classmap entries now.
Explicit namespaces
OR
Keep the namespaces and add them in calls to ->call().
Wherever you write a classname you can fully qualify the class with its namespace (should be \database\seeds\YourClass::class, which can depend on your composer.json settings), or add a use statement at the beginning of the file.
You may have to run composer dump-autoload. It worked for me.
As a side note, it'd be cleaner to use PSR-4 for seeds and migrations (tests already do).
I am using the Repository pattern in my current project. When I try and access the route I get this error
ReflectionException
Class Repositories\UserRepository does not exist
My folder structure is like so
- Respositories
-- UserRepository
In my controller I am doing
use \Repositories\UserRepository;
class UsersController extends ApiController {
protected $user;
public function __construct(UserRepository $user)
{
$this->user = $user;
}
In the UserRepository
<?php namespace \Repositories
class UserRepository {
I am autoloading in composer
"psr-0": {
"Respositories": "app/"
}
Are my namespaces correct? I can not workout why it can't find the class.
1) Don't use prefixed back slashes when defining the namespace.
// No
<?php namespace \Repositories;
// Yes
<?php namespace Repositories;
2) Check your spelling. In your composer.json file, you have Respositories instead of Repositories.
maybe your laravel hasn't load your repository, if thus, just simply run this
command composer dumpautoload
if this occurred on your deployment server, have read this article regarding on this error http://www.tagipuru.xyz/2016/07/09/repository-class-does-not-exist-in-laravel/