Использование пространств имен: импорт/создание псевдонима имени

(PHP 5 >= 5.3.0)

Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортирование - это важная особенность пространств имен. Это похоже на возможность файловых систем unix создавать символические ссылки на файл или директорию.

Пространства имен PHP поддерживают три вида создания псевдонима имени или импорта: создание псевдонима для имени класса, создание псевдонима для имени интерфейса и для имени пространства имен. Обратите внимание, что импорт функций или констант не поддерживается.

В PHP создание псевдонима имени выполняется с помощью оператора use. Вот пример, показывающий 3 типа импорта:

Пример #1 импорт/создание псевдонима имени с помощью оператора use

<?php
namespace foo;
use 
My\Full\Classname as Another;

// это тоже самое, что и использование My\Full\NSname как NSname
use My\Full\NSname;

// импортирование глобального класса
use ArrayObject;

$obj = new namespace\Another// создает экземпляр класса foo\Another
$obj = new Another// создает объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // создает объект класса ArrayObject
// без выражения "use ArrayObject" мы создадим объект класса foo\ArrayObject
?>
Обратите внимание, что для имен в пространстве имен (абсолютные имена, содержащие разделитель пространств имен, такие как Foo\Bar, в отличие от глобальных имен, которые его не содержат, такие как FooBar) нет необходимости в начальном обратном слеше (\) и его присутствие там не рекомендуется, так как импортируемые имена должны быть абсолютными и не обрабатываются относительно текущего пространства имен.

PHP дополнительно поддерживает удобное сокращение для задания нескольких операторов use в одной и той же строке

Пример #2 импорт/создание псевдонима имени с помощью оператора use, комбинирование нескольких операторов use

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// создает объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
?>

Импорт выполняется во время компиляции, и не влияет на имена динамических классов, функций или констант.

Пример #3 Импорт и динамические имена

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// создает объект класса My\Full\Classname
$a 'Another';
$obj = new $a;      // создает объект класса Another
?>

В дополнение, импорт распространяется только на неполные и полные имена. Абсолютные имена не затрагиваются операцией импорта.

Пример #4 Импортирование и абсолютные имена

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// создает объект класса My\Full\Classname
$obj = new \Another// создает объект класса Another
$obj = new Another\thing// создает объект класса My\Full\Classname\thing
$obj = new \Another\thing// создает объект класса Another\thing
?>

Scoping rules for importing

Ключевое слово use должно быть указано в самом начале файла (в глобальной области) или внутри объявления пространства имен. Это необходимо потому, что импорт выполняется во время компиляции, а не во время исполнения, поэтому оно не может быть заключено в блок. Следующий пример показывает недопустимое применение ключевого слова use:

Пример #5 Недопустимое правило импорта

<?php
namespace Languages;

class 
Greenlandic
{
    use 
Languages\Danish;

    ...
}
?>

Замечание:

Правила импорта задаются на каждый файл отдельно. Это означает, что присоединяемые файлы НЕ будут наследовать правила импорта из родительского файла.

Коментарии

The "use" keyword can not be declared inside the function or method. It should be declared as global, after the "namespace" as:

<?php

namespace mydir
;

// works perfectly
use mydir/subdir/Class1 as Class1;

function 
fun1()
{
   
// Parse error: syntax error, unexpected T_USE
   
use mydir/subdir/Class1 as Class1;
}

class 
Class2
{
    public function 
fun2()
    {
       
// Parse error: syntax error, unexpected T_USE
       
use mydir/subdir/Class1 as Class1;
    }
}
?>
2010-07-15 05:01:17
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Because imports happen at compile time, there's no polymorphism potential by embedding the use keyword in a conditonal.

e.g.:

<?php
if ($objType == 'canine') {
  use 
AnimalCanine as Beast;
}
if (
$objType == 'bovine') {
  use 
AnimalBovine as Beast;
}

$oBeast = new Beast;
$oBeast->feed();
?>
2010-12-02 00:07:28
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
Importing and aliasing an interface name is also supported.
2011-01-11 08:26:49
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
If you are testing your code at the CLI, note that namespace aliases do not work!

(Before I go on, all the backslashes in this example are changed to percent signs because I cannot get sensible results to display in the posting preview otherwise. Please mentally translate all percent signs henceforth as backslashes.)

Suppose you have a class you want to test in myclass.php:

<?php
namespace my
%space;
class 
myclass {
 
// ...
}
?>

and you then go into the CLI to test it. You would like to think that this would work, as you type it line by line:

require 'myclass.php';
use my%space%myclass; // should set 'myclass' as alias for 'my%space%myclass'
$x = new myclass; // FATAL ERROR

I believe that this is because aliases are only resolved at compile time, whereas the CLI simply evaluates statements; so use statements are ineffective in the CLI.

If you put your test code into test.php:
<?php
require 'myclass.php';
use 
my%space%myclass;
$x = new myclass;
//...
?>
it will work fine.

I hope this reduces the number of prematurely bald people.
2011-08-14 18:26:15
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
(All the backslashes in namespaces are slashes because I can't figure out how to post backslashes here.)

You can have the same "use" for a class and a namespace. For example, if you have these files:

<?php
// foo/bar.php
namespace foo;

class 
bar
{
    public function 
__toString ()
    {
        return 
'foo\bar\__toString()';
    }
}
?>

<?php
// foo/bar/MyClass.php
namespace foo/bar;

class 
MyClass
{
    public function 
__toString ()
    {
        return 
'foo\bar\MyClass\__toString()';
    }
}
?>

In another namespace, you can do:
<?php
namespace another
;
require_once 
'foo/bar.php';
require_once 
'foo/bar/MyClass.php';

use 
foo/bar;

$bar = new bar();
echo 
$bar."\n";

$class = new bar/MyClass();
echo 
$class."\n";
?>

And it will makes the following output:
foo\bar\__toString()
foo\bar\MyClass\__toString()
2012-05-11 16:34:40
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
You are allowed to "use" the same resource multiple times as long as it is imported under a different alias at each invocation.

For example:

<?php
use Lend;
use 
Lendl1;
use 
Lendl1 as l3;
use 
Lendl2;
use 
Lendl1Keller;
use 
Lendl1Keller as Stellar;
use 
Lendl1Keller as Zellar;
use 
Lendl2Keller as Dellar;

...

?>

In the above example, "Keller", "Stellar", and "Zellar" are all references to "\Lend\l1\Keller", as are "Lend\l1\Keller", "l1\Keller", and "l3\Keller".
2013-01-02 07:13:13
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
Something that is not immediately obvious, particular with PHP 5.3, is that namespace resolutions within an import are not resolved recursively.  i.e.: if you alias an import and then use that alias in another import then this latter import will not be fully resolved with the former import.

For example:
use \Controllers as C;
use C\First;
use C\Last;

Both the First and Last namespaces are NOT resolved as \Controllers\First or \Controllers\Last as one might intend.
2013-03-11 02:59:11
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
The last example on this page shows a possibly incorrect attempt of aliasing, but it is totally correct to import a trait \Languages\Languages\Danish.
2013-04-03 13:02:25
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
2013-04-07 16:32:55
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
The <?php use ?> statement does not load the class file. You have to do this with the <?php require ?> statement or by using an autoload function.
2014-01-30 23:08:48
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
I was attempting to use something like this:

<?php
use $my_variable_namespace
?>

This is not supported. I did this instead:

<?php
if(..)
    use 
MyFirstNamespace;
else
    use 
MyOtherNamespace;
?>
2015-02-13 15:33:56
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
For the fifth example (example #5):

When in block scope, it is not an illegal use of use keyword, because it is used for sharing things with traits.
2015-03-10 19:50:34
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
You'll get here the 
Fatal error: Cannot declare class others\name because the name is already in use
So you can't get two classes <name> inside one namespace
<?php
namespace my 
{
class 
name {
public function 
__construct(){
echo 
'my_namespace_object';
}
}
}
namespace others{
use 
myname;
class 
name {
public function 
__construct(){
echo 
'others_namespace_object';
}
}
$newObject = new name();
}
?>
2015-05-23 10:18:47
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Note the code `use ns1\c1` may refer to importing class `c1` from namespace `ns1` as well as importing whole namespace `ns1\c1` or even import both of them in one line. Example:

<?php
namespace ns1
;

class 
c1{}

namespace ns1c1;

class 
c11{}

namespace main;

use 
ns1c1;

$c1 = new c1();
$c11 = new c1c11();

var_dump($c1); // object(ns1\c1)#1 (0) { }
var_dump($c11); // object(ns1\c1\c11)#2 (0) { }
2016-03-31 10:34:26
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
The keyword "use" has been recycled for three distinct applications: 
1- to import/alias classes, traits, constants, etc. in namespaces, 
2- to insert traits in classes, 
3- to inherit variables in closures. 
This page is only about the first application: importing/aliasing. Traits can be inserted in classes, but this is different from importing a trait in a namespace, which cannot be done in a block scope, as pointed out in example 5. This can be confusing, especially since all searches for the keyword "use" are directed to the documentation here on importing/aliasing.
2016-09-20 13:50:35
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
To clarify the distinction between inserting a trait in a class and importing a trait in a namespace, here is an example where we first import and then insert a trait. 

<?php
namespace ns1
;
trait T {
  static 
$a "In T";
}

namespace ns2;
use 
ns1T// Importing the name of trait ns1\T  in the namespace ns2
class 
  use 
T// Inserting trait T in the class C, making use of the imported name. 


namespace main;
use 
ns2C;
echo 
C::$a// In T;
2016-09-20 14:18:47
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Note that "use" importing/aliasing only applies to the current namespace block.

<?php

namespace SuperCoolLibrary
{
    class 
Meta
   
{
        static public function 
getVersion()
        {
            return 
'2.7.1';
        }
    }
}

namespace
{
    use 
SuperCoolLibraryMeta;
    echo 
Meta::getVersion();//outputs 2.7.1
}

namespace
{
    echo 
Meta::getVersion();//fatal error
}

?>

To get the expected behavior, you'd use:
class_alias('SuperCoolLibrary\Meta','Meta');
2016-09-30 13:53:08
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
In Chinese,there is an error in translation:
// 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象
it should be
// 如果不使用 "use ArrayObject" ,则实例化一个 foo\ArrayObject 对象

/*********************************************/
中文下翻译有错误
// 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象
这句话应该是
// 如果不使用 "use ArrayObject" ,则实例化一个 foo\ArrayObject 对象
2017-02-15 08:16:02
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
I couldn't find answer to this question so I tested myself. 
I think it's worth noting:

<?php
use ExistingNamespaceNonExsistingClass;
use 
ExistingNamespaceNonExsistingClass as whatever;
use 
NonExistingNamespaceNonExsistingClass;
use 
NonExistingNamespaceNonExsistingClass as whatever;
?>

None of above will actually cause errors unless you actually try to use class you tried to import. 

<?php
// And this code will issue standard PHP error for non existing class.
use ExistingNamespaceNonExsistingClass as whatever;
$whatever = new whatever();
?>
2017-05-04 14:13:39
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html
Автор:
Here is a handy way of importing classes, functions and conts using a single use keyword:

<?php
use MizoWeb {
   
PhpWebSite,
   
PhpKeyWord,
   
PhpUnicodePrint,
   
JSJavaScript
   function 
JSprintTotal
   function 
JSprintList
   const 
JSBUAIKUM
   const 
JSMAUTAM
};
?>
2017-10-21 08:03:04
http://php5.kiev.ua/manual/ru/language.namespaces.importing.html

    Поддержать сайт на родительском проекте КГБ