使用命名空间:基础
PHP判断使用哪个命名空间中元素发方法
在这里,可以将 php 命名空间与文件系统作一个简单的类比。在文件系统中访问一个文件有三种方式:
相对文件名形式如foo.txt。它会被解析为 currentdirectory/foo.txt,其中 currentdirectory 表示当前目录。因此如果当前目录是 /home/foo,则该文件名被解析为/home/foo/foo.txt。
相对路径名形式如subdirectory/foo.txt。它会被解析为 currentdirectory/subdirectory/foo.txt。
绝对路径名形式如/main/foo.txt。它会被解析为/main/foo.txt。
PHP命名空间使用了相同的原理。例如,类名通过以下三种方式均可正常引用:
立即学习“PHP免费学习笔记(深入)”;
非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespaceoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
限定名称,或包含前缀的名称,例如 $a = new subnamespaceoo(); 或 subnamespaceoo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespacesubnamespaceoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespaceoo。
完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new currentnamespaceoo(); 或 currentnamespaceoo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespaceoo。
注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 strlen() 或 Exception 或 INI_ALL。
动态类中的命名空间要点
example1.php
<?phpclass classname{ function __construct()
{ echo __METHOD__,"
";
}
}function funcname(){ echo __FUNCTION__,"
";
}const constname = "global";
$a = 'classname';
$obj = new $a; // prints classname::__construct$b = 'funcname';
$b(); // prints funcnameecho constant('constname'), "
"; // prints global?>如果要将下面的代码转换到命名空间中,必须使用完全限定名称(包括命名空间前缀的类名称)。注意因为在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的。
<?phpnamespace namespacename;class classname{ function __construct()
{ echo __METHOD__,"
";
}
}function funcname(){ echo __FUNCTION__,"
";
}const constname = "namespaced";include 'example1.php';
$a = 'classname';
$obj = new $a; // 输出 classname::__construct$b = 'funcname';
$b(); // 输出 funcnameecho constant('constname'), "
"; // 输出 global
/* 注意: 如果使用的双引号,则必须采用 "\namespacename\classname" 的形式,这是因为字符串转义的原因,不明白的请参考PHP转义 */
$a = '
amespacenameclassname';
$obj = new $a; // 输出 namespacenameclassname::__construct$a = 'namespacenameclassname';
$obj = new $a; // 依然输出 namespacenameclassname::__construct$b = 'namespacenameuncname';
$b(); // 输出 namespacenameuncname$b = '
amespacenameuncname';
$b(); // 依然输出 namespacenameuncnameecho constant('
amespacenameconstname'), "
"; // 输出
namespacedecho constant('namespacenameconstname'), "
"; // 依然输出 namespaced?>namespace关键字和NAMESPACE常量
PHP支持两种抽象的访问当前命名空间内部元素的方法,NAMESPACE 魔术常量和namespace关键字。注意:魔术常量是两个下划线
NAMESPACE
常量NAMESPACE的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // 输出 "MyProject" ?>
全局代码,即没有命名空间的时候,输出空字符串。
常量 NAMESPACE 在动态创建名称时很有用,例如:
<?phpnamespace MyProject;function get($classname){
$a = __NAMESPACE__ . '\' . $classname; return new $a;
}?>namespace
关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
<?php namespace MyProject; use blahlah as mine; // see "Using namespaces: importing/aliasing" blahmine(); // calls function blahlahmine() namespacelahmine(); // calls function MyProjectlahmine() namespaceunc(); // calls function MyProjectunc() namespacesubunc(); // calls function MyProjectsubunc() namespacecname::method(); // calls static method "method" of class MyProjectcname $a = new namespacesubcname(); // instantiates object of class MyProjectsubcname $b = namespaceCONSTANT; // assigns value of constant MyProjectCONSTANT to $b ?>
使用命名空间中的别名/导入
允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。
所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名。PHP 5.6开始允许导入函数或常量或者为它们设置别名。
在PHP中,别名是通过操作符 use 来实现的. 下面是一个使用所有可能的五种导入方式的例子:
<?php namespace foo; use MyFullClassname as Another; // 下面的例子与 use MyFullNSname as NSname 相同 use MyFullNSname; // 导入一个全局类 use ArrayObject; // importing a function (PHP 5.6+) use function MyFullunctionName; // aliasing a function (PHP 5.6+)use function MyFullunctionName as func; // importing a constant (PHP 5.6+)use const MyFullCONSTANT; $obj = new namespaceAnother; // 实例化 fooAnother 对象 $obj = new Another; // 实例化 MyFullClassname 对象 NSnamesubnsunc(); // 调用函数 MyFullNSnamesubnsunc $a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象 // 如果不使用 "use ArrayObject" ,则实例化一个 fooArrayObject 对象func(); // calls function MyFullunctionNameecho CONSTANT; // echoes the value of MyFullCONSTANT?>
注意对命名空间中的名称(包含命名空间分隔符的完全限定名称如 FooBar以及相对的不包含命名空间分隔符的全局名称如 FooBar)来说,前导的反斜杠是不必要的也不推荐的,因为导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析。
为了简化操作,PHP还支持在一行中使用多个use语句。
<?phpuse MyFullClassname as Another, MyFullNSname; $obj = new Another; // 实例化 MyFullClassname 对象NSnamesubnsunc(); // 调用函数 MyFullNSnamesubnsunc?>
导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。
<?phpuse MyFullClassname as Another, MyFullNSname; $obj = new Another; // 实例化一个 MyFullClassname 对象$a = 'Another'; $obj = new $a; // 实际化一个 Another 对象?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
<?php use MyFullClassname as Another, MyFullNSname; $obj = new Another; // instantiates object of class MyFullClassname $obj = new Another; // instantiates object of class Another $obj = new Another hing; // instantiates object of class MyFullClassname hing $obj = new Another hing; // instantiates object of class Another hing ?>
解析优先策略
在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。
类的解析优先级
类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如:
<?phpnamespace ABC;class Exception extends Exception {}
$a = new Exception('hi'); // $a 是类 ABCException 的一个对象
$b = new Exception('hi'); // $b 是类 Exception 的一个对象
$c = new ArrayObject; // 致命错误, 找不到 ABCArrayObject 类?>函数和常量的解析优先级
对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。
<?phpnamespace ABC;const E_ERROR = 45;function strlen($str){ return strlen($str) - 1;
}
echo E_ERROR, "
"; // 输出 "45"
echo INI_ALL, "
"; // 输出 "7" - 使用全局常量 INI_ALL
echo strlen('hi'), "
"; // 输出 "1"
if (is_array('hi')) { // 输出 "is not array"
echo "is array
";
} else { echo "is not array
";
}?> 以上就是笔记008 PHP的命名空间 - 中篇的内容,更多相关内容请关注PHP中文网(www.php.cn)!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号