PHP & 理解 Namespace (命名空间)

前言

假设我们有 Tools/A/Foo.php 、Tools/B/Foo.php 文件,这两个 Foo.php 定义了同一个类,然后从 C.php 引入这两个文件,大家说会出现什么情况?代码如下

# Tools/A/Foo.php
class Foo{
	public function __construct() {}
	public function say() {
		echo "Hello,world";
	}
}
# Tools/B/Foo.php
class Foo{
	public function __construct() {}
	public function say() {
		echo "Hello, Tony";
 	}
}
# C.php
include_once "Tools/A/Foo.php";
include_once "Tools/B/Foo.php";
$foo = new Foo();
$foo->say();

你会看到报如下错误:
Fatal error: Cannot declare class Foo, because the name is already in use

该错误表示 Foo 已经重复声明过了,解决方式也很简单,我们拼接独立的前缀不就行了,so 我们来调整一下结构

# Tools/A/Foo.php
class A_Foo{ # 将 Foo 改为 A_Foo
	// 代码不变
}
# Tools/B/Foo.php
class B_Foo{ # 将 Foo 改为 B_Foo
	// 代码不变
}
# C.php
include_once "Tools/A/Foo.php";
include_once "Tools/B/Foo.php";
$a = new A_Foo();
$a->say(); // Hello,world
$b = new B_Foo();
$b->say(); // Hello,Tony

看似问题是解决了,但还面临着其它情况

  1. 引入第三方插件时,名字也可能冲突
  2. 若目录嵌套过深,独立前缀加长,使用时也要跟着加长,可读性差
  3. 团队开发各个成员也容易遇到出现命名重复问题

就算能解决以上这3个问题,每个人的处理方式终究不一样,只会让维护性更差。
说到底还是缺少一种规范,这不 PHP 就新出了 namespace 命名空间这玩意,大家都只要按照它的语法来写问题就迎刃而解。

namespace

好处

  1. 解决命名重复问题
  2. 统一规范,各个文件类名依然可以保留,不再需要单独写 _ 下划线进行兼容。

用法

假设我们的目录结构如下

Tools
	A
		Foo.php
	B
		Foo.php
C.php
# Tools/A/Foo.php
namespace Tools\A; # 新增
class Foo{
	// 内容不变
}
# Tools/B/Foo.php
namespace Tools\B; # 新增
class Foo{
	// 内容不变
}

# C.php
include_once "Tools/A/Foo.php";
include_once "Tools/B/Foo.php";
$a = new Tools\A\Foo();
$a->say(); // Hello,world

$b = new Tools\B\Foo();
$b->say();// Hello,Tony

我们可以看到,两个文件的类名依然一样,只需 new 时带上 namespace 定义的前缀即可,可能有的小伙伴就疑惑了?这种写法不是跟 _ 下划线差不多吗?
注意:还是有差别的,各自文件的类名 Foo 依然保持一致不是吗?
可能你觉得总差点东西,对,名字过长的问题怎么解决? 别急,这不还有另外一个语法 use,我们来改动一下 C.php 代码

# C.php
include_once "Tools/A/Foo.php";
include_once "Tools/B/Foo.php";
use Tools\A\Foo as Foo1;
use Tools\B\Foo as Foo2;
$a = new Foo1();
$a->say(); // Hello,world

$b = new Foo2();
$b->say();// Hello,Tony

现在既保持源类名相同,又能通过 use 方式来简化语法,问题迎刃而解。
对于 PHP 开发者来说掌握 namespace 语法是必须不可缺的。

不知道你注意没有?案例中每次都要通过 include_once 方式引入文件,有没有很繁琐?
另外,使用 namespace 也是有规范的,不能随便就定义自己的前缀,通常需要以你的父目录作为前缀,想要了解更多可以参考我写过的:PHP & 理解 autoload 、PSR-0、PSR-4 的因缘并分析 PS0-0 与 PSR-4 的差异到底在哪里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cookcyq

请作者喝杯暖暖的奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值