命名空间概念:
具体举个例子就明白了,在windows系统中文件 foo.txt 可以同时在目录/home/greg 和 /home/other
中存在,但在同一个目录中不能存在两个 foo.txt
文件。对比于程序中,一样的概念,同一个脚本中,出现同样的类名,常量名,函数名等,会报致命错误,命名空间解决了这一问题。
当然,我们可以在编写代码时,避免出现重名的问题,但是当使用第三方插件时,则很可能遇到,所以在项目初期还是要规划好命名空间。
命名空间用来解决的问题:
1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
注意事项:
1、只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口(interface)、函数和常量。
2、在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。另外,所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。
3、访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或
\INI_ALL。这样可以避免与当前执行脚本方法区分开来。
一、使用命名空间
1、同一个文件中并不提倡使用定义多个命名空间,这里不做介绍,了解可查看官网,
http://php.net/manual/zh/language.namespaces.definitionmultiple.php
<http://php.net/manual/zh/language.namespaces.definitionmultiple.php>
2、使用命名空间:基础
类名可以通过三种方式引用:
方式 描述 不包含命名空间PHP解析 包含命名空间PHP解析
非限定名称 不包含前缀的名称eg: $a=new foo(); 或 foo::test(); foo 会被解析为foo 如果当前命名空间是
Search,foo 将被解析为 Search\foo, 如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称
限定名称 包含前缀的名称eg:$a = new user\foo(); 或 user\foo::test(); foo 会被解析为user\foo
如果当前的命名空间是 Search,则 foo 会被解析为 Search\user\foo
完全限定名称 包含了全局前缀操作符的名称eg:$a = new \user\foo(); 或 \user\foo::test(); foo
总是被解析为user\foo foo 总是被解析为user\foo
eg:
file1.php文件
<?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class
foo { static function staticmethod() {} }
file2.php文件
<?php namespace Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {}
class foo{ static function staticmethod() {} } /* 非限定名称 */ foo(); // 解析为 Foo\Bar
\foo foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。 echo FOO; //
解析为 Foo\Bar\FOO /* 限定名称 */ subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo, // 以及类的方法
staticmethod echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO /* 完全限定名称
*/\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // 解析为类 Foo
\Bar\foo, 以及类的方法 staticmethod echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
3、__NAMESPACE__
常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
二、命名空间和动态语言特征
所谓命名空间的动态,就是一个变量接收路径,例如$a = '\namespacename\classname';。
动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,全部被解析成完全限定名称,因此其前导的反斜杠是不必要的。
eg:
文件1.php
<?php class classname { function __construct() { echo __METHOD__,"\n"; } }
function funcname() { echo __FUNCTION__,"\n"; } const constname = "global"; $a =
'classname'; $obj = new $a; // prints classname::__construct $b = 'funcname'; $b
();// prints funcname echo constant('constname'), "\n"; // prints global
文件2.php
<?php namespace namespacename; class classname { function __construct() { echo
__METHOD__,"\n"; } } function funcname() { echo __FUNCTION__,"\n"; } const
constname ="namespaced"; include '1.php'; $a = 'classname'; $obj = new $a; //
prints classname::__construct $b = 'funcname'; $b(); // prints funcname echo
constant('constname'), "\n"; // prints global $a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct $a =
'namespacename\classname'; $obj = new $a; // also prints
namespacename\classname::__construct $b = 'namespacename\funcname'; $b(); //
prints namespacename\funcname $b = '\namespacename\funcname'; $b(); // also
prints namespacename\funcname echo constant('\namespacename\constname'), "\n";
// prints namespaced echo constant('namespacename\constname'), "\n"; // also
prints namespaced
三、使用命名空间:别名/导入
这里的导入/别名指的是导入/别名”命名空间”,三种别名或导入方式:
1、为类名称使用别名
2、为接口使用别名
3、为命名空间名称使用别名。
注意事项:
1、PHP 5.6开始允许导入函数或常量或者为它们设置别名。
2、前导的反斜杠是不必要的也不推荐的,因为导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析。
导入用use ...,导入+别名用 use ... as
eg:
test1.php文件
<?php namespace Demo2; require('test2.php'); use Demo1; use function Demo1\test
as test1; function test(){ echo 5; } class test{ function test(){ echo 4; } }
test1();//输出1 echo '<hr>'; echo namespace\test();//输出5 echo '<hr>'; $test = new
Demo1\test();//输出2
test2.php文件
<?php namespace Demo1; function test(){ echo 1; } class test{ function
__construct(){ echo 2; } public function test(){ echo 3; } }
热门工具 换一换