Unused use statement with Yii 2 behavior class in Netbeans - php

<?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()

Related

"use" statements in php file

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

PHP's "use" Keyword and Autoloading

My question is in three parts:
Does putting in a use statement trigger the autoloader immediately, or does it wait until the class is used? (lazy-loading)
If autoloading isn't done in a lazy-load fashion, could that negatively affect performance?
Which pattern is best to follow, and why? PhpStorm shows "Unnecessary fully qualified name..." as a code issue when the use statement isn't employed.
Here's an example class definition for a Laravel controller with a use statement:
namespace App\Http\Controllers;
use Carbon\Carbon;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
The same class without the use statement:
namespace App\Http\Controllers;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new \Carbon\Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
1) The class is autoloaded when you perform a new Class() statement.
2) see 1)
3) Which pattern is best to follow and why?:
I'd recommend to use use because you might get into a situation where you have really long namespaces and your code will become unreadable.
From the php docs:
This example attempts to load the classes MyClass1 and MyClass2 from
the files MyClass1.php and MyClass2.php respectively.
<?php
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Namespaces are only an additional feature to organize classes.
EDIT: As #IMSoP pointed out in the comments, new is not the only time the autoloader is triggered. Accessing a class constant, static method, or static property will also trigger it, as will running class_exists.
The use statement can be thought of like a C pre-processing macro, if you're familiar with those: it rewrites the current file at compile time to let you write a short name for a long class, function, or constant name. It doesn't trigger autoloading, as it doesn't care if a class exists or not.
For instance, if you write use Foo\Bar\Baz as X, then everywhere that X is mentioned as a class name, the PHP compiler rewrites that to mention Foo\Bar\Baz instead. Only when code mentioning the class (e.g. new X, X::FOO, X::doSomething()) is actually run does it see if there really is a class Foo\Bar\Baz, and trigger the autoloader as necessary.
The common form use Foo\Bar\Baz is just shorthand for use Foo\Bar\Baz as Baz, assigning the alias Baz to the class name Foo\Bar\Baz.
As the manual points out the alias is only processed at compile time, so dynamic lookups will not use it. In the example above, class_exists('X') will return false, but you can use class_exists(X::class) to expand out the alias - the compiler will automatically substitute the full class name as a string, so at run-time, the expression will be class_exists('\Foo\Bar\Baz').
Whether use statements make your code better is therefore entirely a matter of style: the intent is that your code will be more readable without the long fully-qualified class names, but it will make no difference to how the code actually runs.

How to get the trait name with namespace inside itself?

I want to know if there is a way to get the traits namespace inside itself, I know that I can use self::class to get the classname, but inside a trait it gets the namespace of the class that is using the trait, I don't want to type it's name fixed like new ReflectionClass('trait')
Is there any function or const that can do this?
I'm a little bit confused by your question but if you need the fully qualified name from the trait then you may use __TRAIT__ magic constant and if you only need the namespace of the trait then you may use __NAMESPACE__. For example, declare a trait using a namespace:
namespace App\Http\Controllers\Traits;
trait Methods
{
public function getNamespace()
{
// Get fully qualified name of the trait
echo __TRAIT__; // App\Http\Controllers\Traits\Methods
echo PHP_EOL;
// Get namespace of the trait
echo __NAMESPACE__; // App\Http\Controllers\Traits
}
}
Now, declare a class using another namespace and use that trait inside this class:
namespace App\Http\Controllers;
use App\Http\Controllers\Traits\Methods;
class TraitController
{
use Methods;
public function index()
{
// Call the method declared in trait
$this->getNamespace();
}
}
(new TraitController)->index();
The predefined magic constants __TRAIT__ (since 5.4.0) and __NAMESPACE__ (since 5.3.0) is used so use which one is needed. Tested in php v-5.4.0. Check the demo here.
Also, if you want to get the fully qualified name of the trait from the class that is using it then you may use NameOfTheTrait::class (NameOfTheClass::class/NameOfTheInterface::class) but this is available since php v-5.5.
Also be careful when using self::class. The self::class will give the fully qualified name of the class where you've used it because the self always references the lexical scope (where it's physically used) since the scope of self is determined during the compile time so you may get unexpected results if you inherit a class where a self::class statement is used. In other words, if you call any static method from a child class then the calling context will be still the parent class if you use self in your parent class, in that case you need to use static instead of self. This is actually another topic so please read more on php manual about Late Static Binding.

Use keyword and New keyword in PHP

What is the difference between accessing the class through "use" keyword or declaring it as "new" plus the filepath of the class?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
//if accessed using use keyword
use App\Entity\User;
class SampleController extends Controller
{
public function add(Request $request)
{
//if declared by "use" keyword above
$user = new User();
//if not declared by "use" keyword
$user = new \App\Entity\User();
}
}
If I'm going to use the functions of User class, the results are the same but what's the difference in their declarations?
There is no difference. By using use doesn't include anything. It just imports the specified namespace (or class) to the current scope
new \App\Entity\User(); is same as new User();
You can find more details How does the keyword "use" work in PHP and can I import classes with it?
The use keyword produces an alias for a class or a namespace.
The as keyword introduces the alias. Without as, the alias is the last component of the namespace or class path:
use App\Entity\User as OneUser;
OneUser is the same thing as \App\Entity\User and can be used instead of it everywhere in the current file.
use App\Entity\User;
Here the alias is User (the last component of App\Entity\User). It is the same as (but shorter than):
use App\Entity\User as User;
Aliased are used to write less; the code is easier to read this way.
The aliases are processed at compile time and they are visible only in the file where they are created. The mere presence of the use statement does not have any effect; it only creates a shorter name for a class or namespace but this shorter name is valid only during the compilation of the file that contains it.
The aliased class names are not expanded inside strings. During the compile time they are just text. During the runtime, 'User' is not the same as 'App\Entity\User'.
Accordingly, class_exists('User') returns FALSE but class_exists('App\Entity\User') returns TRUE.
For more insights about how PHP resolves the aliases, read the "Using namespaces: Basics" documentation page.

performance and the use statment PHP, Laravel 4.x

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).

Categories