PHP命名空间 taro Posted on Mar 17 2021 PHP 代码审计 # 命名空间概述 参照PHP手册 https://www.php.net/manual/zh/language.namespaces.rationale.php >(PHP 5 >= 5.3.0, PHP 7) 什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。 在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题: 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。 # 定义命名空间 >虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。 命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间,除了一个以外:declare关键字。 # 定义子命名空间 >与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义 # 使用 >在讨论如何使用命名空间之前,必须了解 PHP 是如何知道要使用哪一个命名空间中的元素的。可以将 PHP 命名空间与文件系统作一个简单的类比。在文件系统中访问一个文件有三种方式: 1. **相对文件名形式** 如foo.txt。它会被解析为 `currentdirectory/foo.txt`,其中 `currentdirectory` 表示当前目录。因此如果当前目录是 `/home/foo`,则该文件名被解析为`/home/foo/foo.txt`。 2. **相对路径名形式** 如`subdirectory/foo.txt`。它会被解析为 `currentdirectory/subdirectory/foo.txt`。 3 **绝对路径名形式** 如`/main/foo.txt`。它会被解析为`/main/foo.txt`。 PHP 命名空间中的元素使用同样的原理。例如,类名可以通过三种方式引用: 1. **非限定名称**,或不包含前缀的类名称,例如 `$a=new foo()`; 或 `foo::staticmethod()`;。如果当前命名空间是 `currentnamespace`,foo 将被解析为 `currentnamespace\foo`。如果使用 `foo` 的代码是全局的,不包含在任何命名空间中的代码,则 `foo` 会被解析为`foo`。 **警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。** 2. **限定名称**,或包含前缀的名称,例如 `$a = new subnamespace\foo();` 或 `subnamespace\foo::staticmethod();`。如果当前的命名空间是 `currentnamespace`,则 foo 会被解析为 `currentnamespace\subnamespace\foo`。如果使用 `foo` 的代码是全局的,不包含在任何命名空间中的代码,`foo` 会被解析为`subnamespace\foo`。 3. **完全限定名称**,或包含了全局前缀操作符的名称,例如, `$a = new \currentnamespace\foo();` 或 `\currentnamespace\foo::staticmethod();`。在这种情况下,`foo` 总是被解析为代码中的文字名(literal name)`currentnamespace\foo`。 PHP-disable_functions-绕过手札 代码注入绕过手札