I am a beginner in Laravel and while learning about "namespace" and "use" statements, I found that, for example, in Controllers, when we first write "use" statements it should be repeated inside of the function.
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
Why is this working so? Why is not it enough to write "use" statements once without repeating in a function? And also, if I will create another Controller with the same namespace, should I write the same "use" statements there as well?
There are two different use in PHP:
To alias namespaced names,
to apply traits to classes.
The use at the top of the file aliases namespaced names into shorter local ones. Literally their only use is so you can write DispatchesJobs inside this one file instead of having to always use the fully qualified name \Illuminate\Foundation\Bus\DispatchesJobs.
use inside a class applies that trait to the class.
In this case you could omit the first use to alias the trait, and apply it using its fully qualified name:
namespace App\Http\Controllers;
class Controller extends \Illuminate\Routing\Controller {
use \Illuminate\Foundation\Bus\DispatchesJobs;
...
}
This does exactly the same thing, but is obviously rather verbose. Establishing a few aliases at the top of the file allows your following code to be terser.
Using keyword use outside class is just importing specific part called trait.
And using keyword use inside class is actually inheriting or implements to use that trait
Related
At the top of file, outside the class, we have:
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
Inside the class, we have:
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
Why it is repeated?
These are traits, which add a defined set of functionality to the class. You can look up this functionality in the Laravel API docs:
https://laravel.com/api/5.6/Illuminate/Foundation/Auth/Access/AuthorizesRequests.html
https://laravel.com/api/5.6/Illuminate/Foundation/Validation/ValidatesRequests.html
https://laravel.com/api/5.6/Illuminate/Foundation/Auth/Access/AuthorizesRequests.html
The use statements up the top are part of PHP's namespaces, which you'll want to get familiar with - this pattern is used all over Laravel's code. Having the use Foo\Bar\Hello\World up the top of the file allows you to do stuff like new World instead of typing out the full new \Foo\Bar\Hello\World throughout the code.
I would like to Use the same class Helper, located at App\Helpers\Helper, in two different files within the same namespace.
For example:
Class A:
<?php
namespace App\Services;
Use Helper;
class A {...}
Class B:
<?php
namespace App\Services;
Use Helper;
class B {...}
However, this is not allowed. The error is:
Cannot use App\Helpers\Helper as Helper because the name is already in use
I could rename the Helper class in my second file and say Use Helper as SomethingElse, but this seems like a messy solution especially if I want to use this Helper in many more than two classes.
Is there a workaround for this?
You most probably already have an included class that goes by that name, the likely problem is that you have a class by that name in another namespace (and said class has been included). You can use both classes (from different namespaces with the same name) by aliasing or using fully qualified names of the classes.
Read this properly.
Is there a central place where I can put 'use' statements so I don't have to keep doing things like this with every single controller I create?
<?php namespace App/Http/Controllers
use Session;
use Auth;
use Input;
use Log;
use Carbon;
use Response;
use Illuminate\Routing\Controller;
class BlaBlaController extends Controller {}
Just seems to violate DRYness and seems inefficient.
Short answer: No.
The 'use' statements are resolving the namespaces for that file, so you can't inherit them from other files. It doesn't violate DRY because there isn't actually any logic that is being repeated.
Now if you don't want to have to include those use statement in every controller then you can just resolve the facade out of the global scope whenever you use it. For example the following will work from any namespace, without needing a use statement.
\Input::all();
In my opinion it looks a little cleaner to just include the use statement, but either will work.
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\Category;
use app\components\NewsBehavior;
class ModelTestController extends Controller
{
The class app\components\NewsBehavior exists, but Netbeans gives warning:
Unused use statement (on the line: use app\components\NewsBehavior;).
NewsBehavior class can not be use directly since it's behavior.
It means you defined it, but didn't use it (at least explicitly) within the current class.
If your don't need it in current class, just remove this declaration.
Otherwise if you configuring behaviors class like a string (for example: 'class' => 'app\components\NewsBehavior', obviously this declared class is not used directly and in the current form this declaration in use is redundant.
However there is another way of passing class with static className() method:
'class' => NewsBehavior::className(),
If you will use that, that IDE notice will disappear since now you are explicitly referring to that class.
Official docs:
yii\base\Object className()
Are there performance considerations when importing classes with the use statement in PHP and more specifically laravel 4.x ?
for example often times i have many use statements in my controllers as such:
use OrganisationController;
use Input;
use Redirect;
use Validator;
use View;
use Organisation;
use Sentry;
use User;
use Str;
use Lang;
use Application;
use Job;
use Upload;
class ApplicationController extends OrganisationController {
...
In my opinion, it should not effect on performance because, when you use a class that is not in the same namespace you use it with a preceding backslash like
\View::make(...);
This way you just telling that, the View class is within the global namespace, to make the code clean you can use use statement top of your class like
use \View, \Redirect, \Validator; // more
class WhatEver extends BaseController {
function index()
{
//...
return View::make(...);
}
}
So, in either way, php is loading (include/require) the class whenever it founds any use of the class but when it's not in the scope of current namespace you must provide the namespace and it could be directly from the code like
\View::make(...);
Or maybe using a use statement to keep your code clean but in both ways, php is loading the class during run time (if not already loaded) but you have to provide the right location (with namespace).