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

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

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

PHP может создавать псевдонимы имени/импортировать константы, функции, классы, интерфейсы и пространства имён.

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

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

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

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

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

// импортирование функции
use function My\Full\functionName;

// псевдоним функции
use function My\Full\functionName as func;

// импортирование константы
use const My\Full\CONSTANT;

$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
func(); // вызывает функцию My\Full\functionName
echo CONSTANT// выводит содержимое константы My\Full\CONSTANT
?>
Обратите внимание, что для имён в пространстве имён (абсолютные имена, содержащие разделитель пространств имён, такие как 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
?>

Обзор правил для импорта

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

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

<?php
namespace Languages;

function 
toGreenlandic()
{
    use 
Languages\Danish;

    
//...
}
?>

Замечание:

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

Описание группирования в одном операторе use

Классы, функции и константы, импортируемые из одного и того же namespace, могут группироваться в одном операторе use.

<?php

use some\namespace\ClassA;
use 
some\namespace\ClassB;
use 
some\namespace\ClassC as C;

use function 
some\namespace\fn_a;
use function 
some\namespace\fn_b;
use function 
some\namespace\fn_c;

use const 
some\namespace\ConstA;
use const 
some\namespace\ConstB;
use const 
some\namespace\ConstC;

// Эквивалентно следующему групповому использованию
use some\namespace\{ClassAClassBClassC as C};
use function 
some\namespace\{fn_afn_bfn_c};
use const 
some\namespace\{ConstAConstBConstC};
add a note add a note

User Contributed Notes 20 notes

up
130
dominic_mayers at yahoo dot com
7 years ago
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.
up
110
anon
10 years ago
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.
up
73
k at webnfo dot com
11 years ago
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
up
32
Mawia HL
6 years ago
Here is a handy way of importing classes, functions and conts using a single use keyword:

<?php
use Mizo\Web\ {
  
Php\WebSite,
  
Php\KeyWord,
  
Php\UnicodePrint,
  
JS\JavaScript,
   function
JS\printTotal,
   function
JS\printList,
   const
JS\BUAIKUM,
   const
JS\MAUTAM
};
?>
up
24
xzero at elite7hackers dot net
6 years ago
I couldn't find answer to this question so I tested myself.
I think it's worth noting:

<?php
use ExistingNamespace\NonExsistingClass;
use
ExistingNamespace\NonExsistingClass as whatever;
use
NonExistingNamespace\NonExsistingClass;
use
NonExistingNamespace\NonExsistingClass 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 ExistingNamespace\NonExsistingClass as whatever;
$whatever = new whatever();
?>
up
16
me at ruslanbes dot com
8 years ago
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
ns1\c1;

class
c11{}

namespace
main;

use
ns1\c1;

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

var_dump($c1); // object(ns1\c1)#1 (0) { }
var_dump($c11); // object(ns1\c1\c11)#2 (0) { }
up
25
c dot 1 at smithies dot org
12 years ago
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.
up
22
x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org
11 years ago
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
Lend\l1;
use
Lend\l1 as l3;
use
Lend\l2;
use
Lend\l1\Keller;
use
Lend\l1\Keller as Stellar;
use
Lend\l1\Keller as Zellar;
use
Lend\l2\Keller 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".
up
19
cl
11 years ago
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.
up
3
ultimater at gmail dot com
7 years ago
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
SuperCoolLibrary\Meta;
    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');
up
3
ZhangLiang
7 years ago
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 对象
up
1
eithed at google mail
3 years ago
Bear in mind that it's perfectly fine to alias namespaces, ie:

<?php
use A\B\C\D\E\User;

new
User();
?>

can be also written as:

<?php
use A\B\C\D\E as ENamespace;

new
ENamespace\User();
?>

however following will not work:

<?php
use A\B\C\D\E as ENamespace;
use
ENamespace\User;

new
User();
?>

> PHP Error:  Class "ENamespace\User" not found
up
0
info at ensostudio dot ru
3 years ago
Note: you can import not existed items without errors:
<?php
use UndefinedClass;
use function
undefined_fn;
use const
UNDEFINED_CONST;
?>
but you cant use/call they:
<?php
$new UndefinedClass
; // Error: Use of undefined class
use function undefined_fn; // Error: Use of undefined function
use const UNDEFINED_CONST; // Error: Use of undefined constant
?>
up
1
thinice at gmail.com
13 years ago
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
Animal\Canine as Beast;
}
if (
$objType == 'bovine') {
  use
Animal\Bovine as Beast;
}

$oBeast = new Beast;
$oBeast->feed();
?>
up
-1
Anonymous
11 years ago
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.
up
-4
kelerest123 at gmail dot com
9 years ago
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.
up
-5
dominic_mayers at yahoo dot com
7 years ago
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
ns1\T; // Importing the name of trait ns1\T  in the namespace ns2
class C {
  use
T; // Inserting trait T in the class C, making use of the imported name.


namespace
main;
use
ns2\C;
echo
C::$a; // In T;
up
-10
Joey
6 years ago
For those hoping for an easy fix of DRY with {} unfortunately you can't nest it or do anything cool with it. In case you can only have one per use and if you don't have one then the whole use is assumed to be wrapped in brackets. That means if you do have one you can't use , as normal with use!

Not possible:

    use A\B\C\{
            D, E,
            F\{X, Y, Z}
        },
        X\Y\Z,
        H\{
            I\{
                Y\Y\Y\Y\Y,
                Z, H, E
            },
            J\{
                A\{
                    G\H\J
                    B\N
                },
                G\H\J
            }
        };
up
-7
Dhairya Lakhera
4 years ago
namespace test{

    use test\xyz\tikku;
    use test\xyz\tikku as class_alias;
    use function test\xyz\tikku\foo;
    use function test\xyz\tikku\foo as func_alias;
    use const test\xyz\tikku\ABC;
    use const test\xyz\tikku\ABC as const_alias;
   

   

    $obj=new tikku;
    $obj->Display();  // I am in  test\xyz namespace

    $obj=new tikku\dhairya;
    $obj->Display();   // I am in test\xyz\tikku namespace

    $obj=new class_alias\dhairya;
    $obj->Display();   // I am in test\xyz\tikku namespace

    $obj=new \class_alias\dhairya;
    $obj->Display();  // I am in class_alias namespace

}

namespace test\xyz{

   class tikku{
    function Display(){
        echo "I am in ".__namespace__." namespace<br/><hr/>";
    }
   }
}

namespace test\xyz\tikku{

   class dhairya{
    function Display(){
        echo "I am in ".__namespace__." namespace<br/><hr/>";
    }
   }
}

namespace class_alias{

   class dhairya{
    function Display(){
        echo "I am in ".__namespace__." namespace<br/><hr/>";
    }
   }
}
up
-8
www.codewars.com
4 years ago
amazing!!

use function strval as numberToString;

var_dump(numberToString(123));

//print
//string(3) "123"
To Top