现代PHP一(命名空间)

 

1.命名空间的定义

命名空间就是用虚拟的类似目录层次结构的方式组织PHP代码,


2.为什么要使用命名空间


避免与其他团队或个人代码融合时产生类名冲突,并遵循PSR-4代码加载规范


3.命名空间的声明与使用

(1)命名空间的声明

命名空间的声明以namespace 关键字开头的语句并以;结尾,且必须在
<?php 后的第一行使用
如:

<?php
namespace Pay;

如果有子命名空间可以加入 \子命名空间
如:

<?php
namespace Pay/AliPay

(2)命名空间的使用


命名空间的使用是使用use关键字

比如 :我们可以直接使用 

use Pay\AliPay; //声明一般在namespace 后面
$aliPay = new AliPay();

而不用在页面的每个需要使用AliPay的地方使用繁琐的语句来实例化

$aliPay = new \Pay\AliPay();

引入命名空间的时候也有可能有重名的类:
比如:

use Foo/HttpResponse;
use My/HttpResponse;
$httpResponse = new HttpResponse();

这个时候解释器就不清楚你想用的到底是上面的类还是下面的类了,这个时候你可以使用 as 关键字给你引入的命名空间起上简单的别名。
use Foo/HttpResponse as Fres;
use My/HttpResponse as Mres;  
$httpResponse = new Mres();

这样系统就很直接了当的知道你要实例化的是  My/HttpResponse 了。


(3) 命名空间的误区

我一直也怀疑,学了上面的命名空间,我是不是就可以直接使用命名空间来解决我的代码引入的问题了?我们来看个栗子:
A/TestA.php

<?php
namespace A;
class TestA{
	public function sayHi(){
	    echo 'Hi';
	}
}

TestB.php

<?php
use A\TestA;
$a = new  TestA();
$a->sayHi();

然后我们执行 TestB.php

HP Fatal error:  Class 'A\TestA' not found in TestB.php on line 2

额,怎么说好的命名空间自动引入的呢,不是忽悠人的嘛。

别生气,PSR-4 规范中提到的命名空间自动引入是有前提条件的,需要修改自动引入机制。
PHP默认的自动引入类是查找当前文件是否有需要实例化的类名,如果没有,则查找全局的包和扩展类中是否有,都没有就只能报错了。那么我们怎么才能不报错呢?将如下代码



spl_autoload_register(function ($class) {
    if ($class) {
        $file = str_replace('\\', '/', $class);
        $file .= '.php';
        if (file_exists($file)) {
            include $file;
        }
    }
});
加入TestB.php中
<?php
namespace B;
use A\TestA;
spl_autoload_register(function ($class) {
    if ($class) {
        $file = str_replace('\\', '/', $class);
        $file .= '.php';
        if (file_exists($file)) {
            include $file;
        }
    }
});
$a = new  TestA();
$a->sayHi();

然后我们执行 TestB.php

Hi

获得了预期的结果,不知道你发没发现,我们使用命名空间时 spl_autoload_register 函数中我们纯粹是使用替换规则替换了一下 '\',这样我们其实可以得出个结论,我们使用‘_’|'::' 或者其他符合变量命名
规则的取名都可以作为命名空间的名字,但是一般为了替换方便,我们约定俗成的使用了'\'.

至于更为复杂的命名空间简化串,可以参考,PSR-4中的例子
https://www.php-fig.org/psr/psr-4/examples/


4. 例外

全局命名空间里面有个例外,就是 Exception

我们在使用命名空间的时候,如果想使用系统的Exception 必须使用 

$e = new \Exception();
如果直接使用:
$e = new Exception();

会报错,找不到当前命名空间下的Exception,不过好在大部分的框架重新封装了Exception,大部分都会自动引入框架的异常处理类。不过出现报错的时候,一般可能是这个原因。


5. 使用命名空间中的函数和常量

使用前提,php version >= 5.6

使用规则:

<?php 

use func Home\funcname;

funcname();

<?php

use constant Home\API_KEY;

echo API_KEY;







猜你喜欢

转载自blog.csdn.net/wujiangwei567/article/details/79518109