©
Ce document utilise Manuel du site Web PHP chinois Libérer
(PHP 5 >= 5.3.0)
允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。
所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名。PHP 5.6开始允许导入函数或常量或者为它们设置别名。
在PHP中,别名是通过操作符 use 来实现的. 下面是一个使用所有可能的五种导入方式的例子:
Example #1 使用use操作符导入/使用别名
<?php
namespace foo ;
use My \ Full \ Classname as Another ;
// 下面的例子与 use My\Full\NSname as NSname 相同
use My \ Full \ NSname ;
// 导入一个全局类
use ArrayObject ;
// importing a function (PHP 5.6+)
use function My \ Full \ functionName ;
// aliasing a function (PHP 5.6+)
use function My \ Full \ functionName as func ;
// importing a constant (PHP 5.6+)
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 (); // calls function My\Full\functionName
echo CONSTANT ; // echoes the value of My\Full\CONSTANT
?>
为了简化操作,PHP还支持在一行中使用多个use语句
Example #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
?>
导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。
Example #3 导入和动态名称
<?php
use My \ Full \ Classname as Another , My \ Full \ NSname ;
$obj = new Another ; // 实例化一个 My\Full\Classname 对象
$a = 'Another' ;
$obj = new $a ; // 实际化一个 Another 对象
?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
Example #4 导入和完全限定名称
<?php
use My \ Full \ Classname as Another , My \ Full \ NSname ;
$obj = new Another ; // instantiates object of class My\Full\Classname
$obj = new \ Another ; // instantiates object of class Another
$obj = new Another \ thing ; // instantiates object of class My\Full\Classname\thing
$obj = new \ Another \ thing ; // instantiates object of class Another\thing
?>
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword:
Example #5 Illegal importing rule
<?php
namespace Languages ;
class Greenlandic
{
use Languages \ Danish ;
...
}
?>
Note:
Importing rules are per file basis, meaning included files will NOT inherit the parent file's importing rules.
[#1] sernuzh at gmail dot com [2015-05-23 07:18:47]
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 my\name;
class name {
public function __construct(){
echo 'others_namespace_object';
}
}
$newObject = new name();
}
?>
[#2] kelerest123 at gmail dot com [2015-03-10 17:50:34]
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.
[#3] Dr. Gianluigi "Zane" Zanettini [2015-02-13 13:33:56]
I was attempting to use something like this:
<?php
use $my_variable_namespace
?>
This is not supported. I did this instead:
<?php
if(..)
use My\First\Namespace;
else
use My\Other\Namespace;
?>
[#4] anon [2014-01-30 21:08:48]
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.
[#5] k at webnfo dot com [2013-04-07 13:32:55]
Note that you can not alias global namespace:
use \ as test;
echo test\strlen('');
won't work.
[#6] Anonymous [2013-04-03 10:02:25]
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.
[#7] cl [2013-03-11 00:59:11]
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.
[#8] x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org [2013-01-02 05:13:13]
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".
[#9] samuel dot roze at gmail dot com [2012-05-11 13:34:40]
(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()
[#10] c dot 1 at smithies dot org [2011-08-14 15:26:15]
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.
[#11] Jan Tvrdk [2011-01-11 06:26:49]
Importing and aliasing an interface name is also supported.
[#12] thinice at gmail.com [2010-12-01 22:07:28]
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();
?>
[#13] nsdhami at live dot jp [2010-07-15 02:01:17]
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;
}
}
?>