命名空间关键技术
一、关键字和常用术语
1、完全限定名称
:从全局空间开始查找的成员,类似绝对路径。
2、限定名称
:从当前空间开始查找的成员,类似相对路径。
3、非限定名称
:仅在当前空间查找的成员,类似当前路径。
4、use
:导入关键字。用法:use ...
。
5、::class
:返回具的完全限定的类名。
Q&A:
Q1: 完成限定名称与限定名称, 非限定名称之间的转换方式是什么?
A1:
1、 非限定名称和限定名称可以直接转化成完全限定名称,区别在于开始查找的位置。
2、 完全限定名称:\
开始。
3、非完全限定名称:至少有一个且不是第一个字符的\
。
4、非限定名称:没有\
。
Q2: use
解决了什么问题?
A2: 先用use
关键字直接导入成员,可以避免写冗长的完全限制名称。
as
解决导入简化完全限定名称时造成命名冲突的问题
Q3: ::class
操作符为什么比__NAMESPACE__
好用? 具体应用场景有哪些?
A3: ::class
:直接返回的完全限定的类名;__NAMESPACE__
:直接返回的当前空间名称。
1、我们一般都直接调用类,所以::class
用的更多。
2、__NAMESPACE__.\Demo\function
:此用法可以避免代码被写死的问题。
二、实例演示
1、完全限定名称访问四类全局成员的方式
//demo2 创建带有命名空间的全局成员
<?php
//创建带命名空间的类
namespace unit1\loai;
class Loai
{
public static function index() : array
{
return [
'className' => __CLASS__
];
}
}
//创建带命名空间的接口
namespace unit1\api;
interface iTest
{
public static function xinchao ();
}
//创建带命名空间的函数
namespace unit1\flx;
function getFuncname () : string
{
return __FUNCTION__;
}
//创建带命名空间的常量
namespace unit1\param;
const SITE_NAME = 'TEXHONG';
//demo1 完全限定名称访问四类全局成员
<?php
//创建命名空间
namespace unit1;
// 1、访问完全限定名称的类
//加载
require 'demo2.php';
//完全限定名称,从全局开始“\”
$result1 = \unit1\loai\Loai::index();
//返回具有完全限定名称的类名
echo '<pre>' .print_r($result1,true);
echo '<hr>';
// 2、访问完全限定名称的接口
//接口需要先实现接口中的方法
class Test implements \unit1\api\iTest
{
public static function xinchao()
{
return class_implements(self::class);
}
}
$result2 = Test::xinchao();
echo '<pre>' .print_r($result2,true);
echo '<hr>';
// 3、访问完全限定名称的函数
$result3 = \unit1\flx\getFuncname();
echo '<pre>' .print_r($result3,true);
echo '<hr>';
// 4、访问完全限定名称的常量
$result4 = \unit1\param\SITE_NAME;
echo '<pre>' .print_r($result4,true);
echo '<hr>';
2、导入四类全局成员的方式
<?php
//导入’use‘
namespace unit1;
//加载
require 'demo2.php';
//导入类
use unit1\loai\Loai;
$result1 = loai::index();
echo '<pre>' .print_r($result1,true);
echo '<hr>';
//导入接口
use unit1\api\iTest;
//接口需要先实现接口中的方法
class Test implements iTest
{
public static function xinchao()
{
return class_implements(self::class);
}
}
$result2 = Test::xinchao();
echo '<pre>' .print_r($result2,true);
echo '<hr>';
//导入函数(和类、接口的区别, 要加上类型)
use function unit1\flx\getFuncname;
$result3 = getFuncname ();
echo '<pre>' .print_r($result3,true);
echo '<hr>';
//导入常量
use const unit1\param\SITE_NAME;
$result4 = SITE_NAME;
echo '<pre>' .print_r($result4,true);
echo '<hr>';
3、全局成员中的别名引用方式
别名:解决导入简化的完全限定名称的成员的同时, 也会带来命名的冲突问题。
function getFuncname () : string
{
//.....
}
//导入函数(和类、接口的区别, 要加上类型)
//如果当前空间已经有函数,则导入会报错,’as‘ 别名可以解决
//别名和原名一样,则可以省略
use function unit1\flx\getFuncname as getFuncnamex;
$result3 = getFuncnamex ();
echo '<pre>' .print_r($result3,true);
echo '<hr>';
有关命名空间的总结:
1、命名空间借鉴了传统的使用目录管理文件的方式, 来管理程序中的全局成员。
2、完全限定名称、非完全限定名称、非限定名称。(都是名称,也就是名字,相当于文件名。)
3、三者区别在于目录层级的深浅。