详细分析PHP 命名空间(namespace)

2020-06-30 19:00:05丽君

使用命名空间:后备全局函数/常量

在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如:

1、在命名空间中访问全局类

<?php
namespace ABC;
class Exception extends Exception {}

$a = new Exception('hi'); // $a 是类 ABCException 的一个对象
$b = new Exception('hi'); // $b 是类 Exception 的一个对象

$c = new ArrayObject; // 致命错误, 找不到 ABCArrayObject 类
?>

对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。

2、 命名空间中后备的全局函数/常量

<?php
namespace ABC;

const E_ERROR = 45;
function strlen($str)
{
  return strlen($str) - 1;
}

echo E_ERROR, "n"; // 输出 "45"
echo INI_ALL, "n"; // 输出 "7" - 使用全局常量 INI_ALL

echo strlen('hi'), "n"; // 输出 "1"
if (is_array('hi')) { // 输出 "is not array"
  echo "is arrayn";
} else {
  echo "is not arrayn";
}
?>

全局空间

如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。

使用全局空间说明

<?php
namespace ABC;

/* 这个函数是 ABCfopen */
function fopen() { 
   /* ... */
   $f = fopen(...); // 调用全局的fopen函数
   return $f;
} 
?>

命名空间的顺序

自从有了命名空间之后,最容易出错的该是使用类的时候,这个类的寻找路径是什么样的了。

<?php
namespace A;
use BD, CE as F;

// 函数调用

foo();   // 首先尝试调用定义在命名空间"A"中的函数foo()
      // 再尝试调用全局函数 "foo"

foo();   // 调用全局空间函数 "foo" 

myfoo();  // 调用定义在命名空间"Amy"中函数 "foo" 

F();    // 首先尝试调用定义在命名空间"A"中的函数 "F" 
      // 再尝试调用全局函数 "F"

// 类引用

new B();  // 创建命名空间 "A" 中定义的类 "B" 的一个对象
      // 如果未找到,则尝试自动装载类 "AB"

new D();  // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
      // 如果未找到,则尝试自动装载类 "BD"

new F();  // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
      // 如果未找到,则尝试自动装载类 "CE"

new B();  // 创建定义在全局空间中的类 "B" 的一个对象
      // 如果未发现,则尝试自动装载类 "B"

new D();  // 创建定义在全局空间中的类 "D" 的一个对象
      // 如果未发现,则尝试自动装载类 "D"

new F();  // 创建定义在全局空间中的类 "F" 的一个对象
      // 如果未发现,则尝试自动装载类 "F"

// 调用另一个命名空间中的静态方法或命名空间函数

Bfoo();  // 调用命名空间 "AB" 中函数 "foo"

B::foo();  // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
      // 如果未找到类 "AB" ,则尝试自动装载类 "AB"

D::foo();  // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
      // 如果类 "BD" 未找到,则尝试自动装载类 "BD"

Bfoo();  // 调用命名空间 "B" 中的函数 "foo" 

B::foo(); // 调用全局空间中的类 "B" 的 "foo" 方法
      // 如果类 "B" 未找到,则尝试自动装载类 "B"

// 当前命名空间中的静态方法或函数

AB::foo();  // 调用命名空间 "AA" 中定义的类 "B" 的 "foo" 方法
       // 如果类 "AAB" 未找到,则尝试自动装载类 "AAB"

AB::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
       // 如果类 "AB" 未找到,则尝试自动装载类 "AB"
?>								 
			 
相关文章 大家在看