使用命名空间:别名/导入
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。
PHP 可以为这些项目导入或设置别名: 常量、函数、类、接口、trait、枚举和命名空间。
   别名是通过操作符 use 来实现的。下面是五种导入方式的例子:
   
示例 #1 使用 use 操作符导入/使用别名
<?php
namespace foo;
use My\Full\Classname as Another;
// 下面的例子与 use 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 Another, My\Full\NSname;
$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
?>导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。
示例 #3 导入和动态名称
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // 实例化一个 My\Full\Classname 对象
$a = 'Another';
$obj = new $a;      // 实际化一个 Another 对象
?>另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
示例 #4 导入和完全限定名称
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // class My\Full\Classname 的实例对象
$obj = new \Another; // class Another 的实例对象
$obj = new Another\thing; // class My\Full\Classname\thing 的实例对象
$obj = new \Another\thing; // class Another\thing 的实例对象
?>导入规则的范围
    use 关键词必须在文件最外层范围
    (全局作用域)或在命名空间声明内。
    由于导入发生在编译时,而不是运行时,所以不能放入块作用域。
    以下例子展示了不合规则的 use 关键词使用示例:
   
示例 #5 不合规的导入规则
<?php
namespace Languages;
function toGreenlandic()
{
    use Languages\Danish;
// ...
}
?>注意:
导入规则独立于每个文件,意味着包含的文件 不会继承父文件的导入规则。
use 声明编组
   
    通过单个 use 语句,可以将来自同一个 namespace 的
    类、函数、常量一起编组导入。
   
<?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 声明
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
  +添加备注
  
用户贡献的备注 17 notes
  
  
  dominic_mayers at yahoo dot com ¶
  
 
  8 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.  
  
  anon ¶
  
 
  11 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.  
  
  Mawia HL ¶
  
 
  7 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
};
?>  
  
  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.  
  
  xzero at elite7hackers dot net ¶
  
 
  7 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();
?>  
  
  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) { }  
  
  c dot 1 at smithies dot org ¶
  
 
  13 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.  
  
  x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org ¶
  
 
  12 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".  
  
  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.  
  
  ultimater at gmail dot com ¶
  
 
  8 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');  
  
  ZhangLiang ¶
  
 
  8 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 对象  
  
  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  
  
  thinice at gmail.com ¶
  
 
  14 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();
?>  
  
  dominic_mayers at yahoo dot com ¶
  
 
  8 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;  
  
  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.  
  
  info at ensostudio dot ru ¶
  
 
  4 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
?>备份地址:http://www.lvesu.com/blog/php/language.namespaces.importing.php