The use of "use" - php

I was just playing around with my IDE and I noticed that when I use the "Fix code" option on a class it adds a bunch of lines on the top of the following type
use Someclass;
use \Ano\therClass;
use Iface;
...
I was wondering what exactly is the purpose of this, since the classes are going to be loaded on demand, is there a need to explicitly declare which classes are going to be used?

Using use you can basically have different objects, functions, etc. with the same name, thanks to namespaces. When you write use in your code, you tell PHP to import items of a namespace and give it an alias.
Read more: http://php.net/manual/en/language.namespaces.importing.php

When U create a class, name it's package with keyword namespace
<?php
/**
* CacheException.php
*/
namespace Doctrine\ORM\Cache;
class CacheException extends Exception {}
Elsewhere use can import only one class from package:
use Doctrine\ORM\Cache\CacheException;
throw new CacheException('Failed to cache');
Also use imports overal package with all it's classes:
use Doctrine\ORM\Cache;
throw new CacheException('Failed to cache');
More at http://php.net/manual/en/language.namespaces.importing.php

Related

Is aliasing namespace within namespace declaration, not namespace import possible in PHP?

I'm writing classes in PHP in deep namespace, but I want it to be easier to access. Is there a way to alias namespace within it's definition, not import? It's okay if it's work-around.
I want to achieve it, becouse its very, very commonly used class in code I have on hands, but moving it into more shallow namespace entirely is not an option.
I've tried to google it but all I found was import namespace aliasing, I havent found anything revelant also anything in docs.
Definition file:
namespace \Something\Really\Annoyingly\Deep AS \MyClass
class MyClass{}
Other file:
namespace \Something\Else;
use MyClass;
$obj = new MyClass();
I used "AS" here for sake of example. I know it will not work, and my question is, is it possible to make it work somehow?
No, it's not possible.
The aliases can only be declared at import time, and are file-based.
If you think about it, you'll realize it doesn't make sense it were possible. There is nothing to be gained and a lot to be able to be broken if this was possible.

Modern PHP Book - Clearification about "use" and "require" when using Namespace

I'm currently reading Modern PHP Book and I'm a little confused since in Chapter 2 the author talks about Namespace and he keeps saying import when he refers to the "use". In fact he states the following...
TIP
You should import code with the use keyword at the top
of each PHP file, immediately after the opening <?php tag or...
The way I understand Namespace is that the use keyword references the namespace of the class but it doesn't import it and you still need to use require or include to import the actual class, correct?
I'm I correct when I say that when using namespace without auto-loading you will need to use require or include to import your classes?
Thanks
If you use autoloader, such as composer, you do not need to import or require PHP files (you only load autoloader file, which actually does all that for you). If you have no autoloader, you have to load files using import or require.
Then, after FILE is loaded, you can use use statements to do actual work with name-spaced items, such as classes, interfaces or traits.
Yes, you're correct. The use keyword in PHP merely aliases a namespace, in that it does what a symlink (on a *nix system) or shortcut (on a Windows system) would.
If you read the manual about PHP namespace basics you'll see that namespaces can be analogous to a filesystem where class/interface/constant/function names can be divided up into folders in order to prevent name-clashes.
If you read the manual section on Namespace Importing you'll see that when we refer to importing in PHP it actually means to create a shortcut of one name to another name (in fact the shortcut analogy above is taken right from the manual)...
This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.
So, while confusing, the use keyword in PHP does not attempt to load (or include) the actual file containing the namespace, but rather just creates an alias for given namespace(s).
This may be very different use of the word import than you may be used to in other languages, where import can mean to load the actual file or package, but in PHP it's important to understand that importing a namespace has nothing to do with autoloading or including files. They are two separate concepts in PHP.
Importing a namespace is so that you can refer to \fully\qualified\namespace\MyClass as simply MyClass inside your namespace rather than having to use the FQN every single time (hence the shortcut analogy).
Autoloading, is for including the actual classes in PHP when they get used in code.
So there's a definite disconnect between the two concepts.
Since you mentioned a Chapter 2 in a book, I'm going to assume that you are still learning PHP, yes?
The use of use is to shorten namespaced classes to their root so that if you have some long namespaced class like
org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException
that needs to be instantiated with
new org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException();
You can use use to refer only to the root unnamespaced class
use org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException;
...
throw new StopExecutionException();
Keep in mind that you still need to have the class's code in your script, so you either include/require that manually by using include or require, or register autoloaders (see spl_autoload_register).
What that does is you define how your namespace maps to your source code's directory structure.
What others here refer to as composer is a package manager that includes an autoloader. At this stage, I personally think it's better to put off learning about this until you have a good grasp of the basics.
If you have an autoloader then use can be used to pull a Trait
Trait file
namespace Blah;
Trait Foo {
protected $somevar;
}
Class file
Class Bar {
use \Blah\Foo; // autoloaded
}
Otherwise, use is used to indicate that you want to either load a given class or alias that class as another
Class Foo {
}
use \Foo as Bar;
Class Something extends Bar {
}

"use" builtin classes without an alias

I see the following code at the top of one of the PHP files im working on.
use DateTime, DateTimeZone;
Is this code useless or is there something I'm missing?
Developers do this to make their lives a bit easier and the code a bit more pretty when working inside namespaces. To explain a bit...
You use namespaces to prevent possible naming collisions with different frameworks. Let's say you work inside a namespace 'MyApp'. Now, because you are now inside of a namespace, you cannot use php's native classes without the leading '\' because those native classes live in the global namespace ( which you identify with '\' before class names ). So if you ever need to use the native DateTime class, you would have to use it with the backslash - \DateTime.
But you can also import things from other namespaces if you know you are going to use them - by using the use keyword after your namespace declaration. That way, you do not have to use the full namespaced name of a class you are going to use, but only the class name itself as you are used to from working without namespaces.
Saying
namespace MyApp;
use DateTime;
Will import the \DateTime class into your MyApp namespace, effectively allowing you to just use DateTime in your code.
You should read more about namespaces on php's website. There's more stuff to be told about namespaces than I can possibly cover in this post.
Presumably, the file in question is under its own namespace.
It's used so that you don't have to use \DateTime in the code.
This code is because it is likely that the source file will also contain a namespace definition. This means that you can access built-in classes only with a leading \ after that namespace definition:
like:
namespace Foo;
$dt = new \DateTime();
To prevent themselves from typing the leading \ or in order to make it possible to include some legacy code, they aliased the classes

How does the keyword "use" work in PHP and can I import classes with it?

I have a file with a class Resp. The path is:
C:\xampp\htdocs\One\Classes\Resp.php
And I have an index.php file in this directory:
C:\xampp\htdocs\Two\Http\index.php
In this index.php file I want to instantiate a class Resp.
$a = new Resp();
I know I can use require or include keywords to include the file with a class:
require("One\Classes\Resp.php"); // I've set the include_path correctly already ";C:\xampp\htdocs". It works.
$a = new Resp();
But I want to import classes without using require or include. I'm trying to understand how use keyword works. I tried theses steps but nothing works:
use One\Classes\Resp;
use xampp\htdocs\One\Classes\Resp;
use htdocs\One\Classes\Resp;
use One\Classes;
use htdocs\One\Classes; /* nothing works */
$a = new Resp();
It says:
Fatal error: Class 'One\Classes\Resp' not found in C:\xampp\htdocs\Two\Http\index.php
How does the keyword use work? Can I use it to import classes?
No, you can not import a class with the use keyword. You have to use include/require statement. Even if you use a PHP auto loader, still autoloader will have to use either include or require internally.
The Purpose of use keyword:
Consider a case where you have two classes with the same name; you'll find it strange, but when you are working with a big MVC structure, it happens. So if you have two classes with the same name, put them in different namespaces. Now consider when your auto loader is loading both classes (does by require), and you are about to use object of class. In this case, the compiler will get confused which class object to load among two. To help the compiler make a decision, you can use the use statement so that it can make a decision which one is going to be used on.
Nowadays major frameworks do use include or require via composer and psr
1) composer
2) PSR-4 autoloader
Going through them may help you further.
You can also use an alias to address an exact class. Suppose you've got two classes with the same name, say Mailer with two different namespaces:
namespace SMTP;
class Mailer{}
and
namespace Mailgun;
class Mailer{}
And if you want to use both Mailer classes at the same time then you can use an alias.
use SMTP\Mailer as SMTPMailer;
use Mailgun\Mailer as MailgunMailer;
Later in your code if you want to access those class objects then you can do the following:
$smtp_mailer = new SMTPMailer;
$mailgun_mailer = new MailgunMailer;
It will reference the original class.
Some may get confused that then of there are not Similar class names then there is no use of use keyword. Well, you can use __autoload($class) function which will be called automatically when use statement gets executed with the class to be used as an argument and this can help you to load the class at run-time on the fly as and when needed.
Refer this answer to know more about class autoloader.
use doesn't include anything. It just imports the specified namespace (or class) to the current scope
If you want the classes to be autoloaded - read about autoloading
Don’t overthink what a Namespace is.
Namespace is basically just a Class prefix (like directory in Operating System) to ensure the Class path uniqueness.
Also just to make things clear, the use statement is not doing anything only aliasing your Namespaces so you can use shortcuts or include Classes with the same name but different Namespace in the same file.
E.g:
// You can do this at the top of your Class
use Symfony\Component\Debug\Debug;
if ($_SERVER['APP_DEBUG']) {
// So you can utilize the Debug class it in an elegant way
Debug::enable();
// Instead of this ugly one
// \Symfony\Component\Debug\Debug::enable();
}
If you want to know how PHP Namespaces and autoloading (the old way as well as the new way with Composer) works, you can read the blog post I just wrote on this topic: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html
You'll have to include/require the class anyway, otherwise PHP won't know about the namespace.
You don't necessary have to do it in the same file though. You can do it in a bootstrap file for example. (or use an autoloader, but that's not the topic actually)
The issue is most likely you will need to use an auto loader that will take the name of the class (break by '\' in this case) and map it to a directory structure.
You can check out this article on the autoloading functionality of PHP. There are many implementations of this type of functionality in frameworks already.
I've actually implemented one before. Here's a link.
I agree with Green, Symfony needs namespace, so why not use them ?
This is how an example controller class starts:
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class WelcomeController extends Controller { ... }
Can I use it to import classes?
You can't do it like that besides the examples above. You can also use the keyword use inside classes to import traits, like this:
trait Stuff {
private $baz = 'baz';
public function bar() {
return $this->baz;
}
}
class Cls {
use Stuff; // import traits like this
}
$foo = new Cls;
echo $foo->bar(); // spits out 'baz'
The use keyword is for aliasing in PHP and it does not import the classes. This really helps
1) When you have classes with same name in different namespaces
2) Avoid using really long class name over and over again.
Using the keyword "use" is for shortening namespace literals. You can use both with aliasing and without it. Without aliasing you must use last part of full namespace.
<?php
use foo\bar\lastPart;
$obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
Namespace is use to define the path to a specific file containing a class e.g.
namespace album/className;
class className{
//enter class properties and methods here
}
You can then include this specific class into another php file by using the keyword "use" like this:
use album/className;
class album extends classname {
//enter class properties and methods
}
NOTE: Do not use the path to the file containing the class to be implements, extends of use to instantiate an object but only use the namespace.

PHP namespaces and the implements keyword

use MyNamespace;
class NonPersistentStorage implements StorageInterface
Both are in MyNamespace. Yet PHP looks for MyNamespace\NonPersistentStorage and StorageInterface (instead of MyNamespace\StorageInterface). Am I missing something?
PHP Namespaces work a bit different than in other languages. When you import a namespace, you aren't really bringing classes into scope, you're just aliasing the namespace. Importing only one level of namespace does absolutely nothing. Even when you import something, you still need to reference its bottommost namespace.
For example, if you have this:
foo.php:
namespace Bar\Baz\Biz;
class Foo
{}
Here is how you use it:
blah.php:
use Bar\Baz\Biz;
$var=new Biz\Foo();
See how I still have to reference it using Biz, even though I imported it?
However, you can get around this using aliases:
blah.php:
use Bar\Baz\Biz\Foo as Foo;
$var=new Foo();
As you can see, I no longer have to qualify it.
Unfortunately, however, there is no "import all" in PHP; if you want to do what's done above, you have to alias each and every class you want to import.
Actually, that "use" declaration does absolutely nothing. You should import (use) namespaces when they are deeper in the namespace hierarchy (e.g. use Foo\Bar\Baz) or when you want to give them an alias (e.g. use Foo as Bar). I think you wanted to declare that the file itself belongs to MyNamespace:
namespace MyNamespace;
class NonPersistentStorage implements StorageInterface { /* ... */ }
Or, you may also want to import separate functions and classes, using the same syntax as for namespaces.
Try using:
use MyNamespace;
class NonPersistentStorage implements MyNamespace\StorageInterface

Categories