命名空间

命名空间并不是新事物,在很多面向对象的编程语言中,都得到了很好的支持,它有效的解决了同一个脚本中的成员命名冲突问题。所以说,命名空间是一种代码封装技术,代码中的每个成员,都是自己的活动空间,彼此互不干扰。
在php中,命名空间主要针对三类成员:函数,常量和类,因为他们三个家伙的作用域都是全局的。所以在同一个脚本中,是不允许重复定义函数,常量和类的。
下面我们用实例来演示:

<?php
const SITE_NAME = 'PHP中文网'; //声明常量SITE_NAME
function sum($n, $m) //声明函数:sum()
{
return $n+$m;
}
class Staff //声明类:Staff
{
private $name = 'peter'; //私有属性name
public function __get($name) //魔术方法__get(),用于外部访问私有属性值
{
return $this->$name;
}
public function __set($name, $value) //魔术方法__set(),用于外部更新私有属性值
{
return $this->$name = $value;
}
}//访问
echo SITE_NAME;
echo '<hr>';
echo sum(10, 20);
echo '<hr>';
echo (new Staff)->name;

现在我们将这三成员,复制一份到下面,这时,当前脚本中就会有二个同名的常量,函数和类了。再次访问一下,会发生什么呢?当然会出错,如果代码会说话,它肯定会说:嗨,哥们,玩我呢?你究竟要访问哪个呀?

但是,我现在就是要在同一个脚本中,访问同名的这三家伙,怎么呢?好办:用:用命名空间。
首先,在代码的第一行,我们写上 namespce 关键字,该关键字可以声明一个命名空间,并且这个关键必须必须是代码的第一行语句,前面不能有任何输出。
例如,我们将这三个成员的命名空间声明为:test1;
再把下面与它名称重复的声明为:test2,再修改一个test2空间中的SITE_NAME常量的值,类中属性name的默认值也修改一下,这样就可以和test1空间的内部区别开了。

<?php
namespace test1;
const SITE_NAME = 'PHP中文网'; //声明常量SITE_NAME
function sum($n, $m) //声明函数:sum()
{
return $n+$m;
}
class Staff //声明类:Staff
{
private $name = 'peter'; //私有属性name
public function __get($name) //魔术方法__get(),用于外部访问私有属性值
{
return $this->$name;
}
public function __set($name, $value) //魔术方法__set(),用于外部更新私有属性值
{
return $this->$name = $value;
}
}
namespace test2;
const SITE_NAME = 'www.php.cn';
function sum($n, $m) //声明函数:sum()
{
return $n+$m;
}
class Staff //声明类:Staff
{
private $name = 'jack'; //私有属性name
public function __get($name) //魔术方法__get(),用于外部访问私有属性值
{
return $this->$name;
}
public function __set($name, $value) //魔术方法__set(),用于外部更新私有属性值
{
return $this->$name = $value;
}
}
//访问
echo SITE_NAME;
echo '<hr>';
echo sum(10, 20);
echo '<hr>';
echo (new Staff)->name;

好,我们再次访问一下。发现,没问题了。为什么现在就可以了,因为这二段代码,他们都有自己的有效范围,这就好比,很多城市,都是一条路:长江路,但我们并不会搞错,因为这些长江路,尽管路名重复,但是它们属性不同的城市。

这里再介绍一个系统魔术常量:__NAMESPCE__,它总是与当前命名空间绑定。
我们现在用这个魔术常量查看一下当前的命名空间是哪个?
echo __NAMESPACE__; //查看当前命名空间
发现当前命名空间是:test2,
现在我想在当前空间test2中,访问test1中的成员,应该怎么做呢?
可以这样访问:

echo '当前命名空间是:'.__NAMESPACE__;
echo '<hr>';
echo SITE_NAME; //访问当前空间中的常量SITE_NAME
echo '<hr>';
echo \test1\SITE_NAME; //访问test1空间中的常量SITE_NAME
echo '<hr>';
echo \test1\sum(40, 50); //访问test1空间中的函数sum()
echo '<hr>';
echo sum(10, 20); //访问当前空间中的函数sum()
echo '<hr>';
$obj1 = new Staff;
echo $obj1->name; //访问当前空间中的类实例属性name
echo '<hr>';
$obj2 = new \test1\Staff;
$obj2->name = 'Tom'; //更新$obj2中的name属性值
echo $obj2->name; //访问test1空间中的类实例属性name

实际开发过程中,在当前空间引入其它空间的成员类型,绝大多数情况,都是类成员,所以php允许使用use关键字,在当前空间中引入其它空间的类成员。
我们再次改写一个代码:
在test2空间声明代码namespace test2后面添加上:
use test1;
use 语句引入命名空间,并不能代替require或include语句,不能自动导入类文件,一定要注意,它只是提供一种命名空间的快捷方式罢了。
另外,use 语句引入命名空间有二个级别:
一是空间级,二是类级。如果是空间级,就是只定位到空间,在访问时,在类名前还要要加上空间名的,只是不用再加\:全局空间符号了。因为use 默认就是从全局空间开始的。
还有就是类级,直接定位到类上. use test1\Staff类。

其实,现在是有问题的,因为当前空间test2也有一个Staff类,命名冲突了。我们可以通过关键as ,给引入的类起个别名来解决: use test1\Staff as test1Staff;

现在访问:
//访问

echo '当前命名空间是:'.__NAMESPACE__;
echo '<hr>';
echo SITE_NAME; //访问当前空间中的常量SITE_NAME
echo '<hr>';
echo \test1\SITE_NAME; //访问test1空间中的常量SITE_NAME
echo '<hr>';
echo \test1\sum(40, 50); //访问test1空间中的函数sum()
echo '<hr>';
echo sum(10, 20); //访问当前空间中的函数sum()
echo '<hr>';
$obj1 = new test1Staff;
echo $obj1->name; //访问当前空间中的类实例属性name
echo '<hr>';
$obj2 = new Staff; //仅定位到空间级
// $obj2->name = 'Tom'; //更新$obj2中的name属性值
echo $obj2->name; //访问test1空间中的类实例属性name

到现在,我们发现,实际上代码的运行空间分为二类:一是全局空间,也叫公共空间,在这里,类,常量,函数等全局成员是不允许重名的。另一类是命名空间,在这个可命名或自定义空间中,这些成员可以与其它空间的成员名称一样,并不会冲突。
还有一点:命名空间是可以分层的。就是你文件目录,有子目录一样。
我们来实例演示一下,
在代码的最下面再写一个类Demo,它的命名空间是:test2/test3,这就是典型的子空间语法:

namespace test2\test3;
class Demo {
const CITY = '合肥';
}

同学们,想一下,为什么要写代码的底部,而不直接跟在test2空间的后面写。
现在在test2空间顶部加上:use test2\test3\Demo;语句,就可以在test2空间使用Demo类了。
现在写上访问语句: echo Demo::CITY;

好,到现在为止,我们遇到了三种命名空间的语法:
第一种:从全局空间反斜杠开始写起,例如 /test1/Staff;这叫:完全限定名称命名空间。其中全局空间标识符反斜杠不可重命名,与目录中的绝对路径很相似。
第二种: 在被访问成员前加上命名空间标识符:例如: test1/sum(),这叫:限定名称的命名空间。你可以理解与文件的相对路径。
第三种:直接访问空间成员,前面不用加任何空间标识符, 例如 new Staff;这叫:非限定名称的命名空间,类似于文件当前目录的概念。

好,命名空间的知识,就讲完了,为了教学方便,我把多个命名空间全部写在一直脚本中,在实际开发中,这不是一个好习惯,应该一个文件,只使用一个命名空间。

转载于:https://www.cnblogs.com/php-cn/p/6827328.html

命名空间:不只是代码封装相关推荐

  1. vuex的命名空间有哪些_vuex模块化和命名空间的实例代码

    这篇文章给大家介绍的内容是关于vuex模块化和命名空间的实例代码 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 因为Vuex Store是全局注册的,不利于较大的项目,引入模块分离 ...

  2. python学习——把计算GC含量的代码封装成函数

    把代码封装成函数的好处是可以重复使用该段代码,并且会使代码结构清晰 例如要计算chr1以及chr2染色体的GC含量,代码如下: 1 # 将代码封装为函数并重复使用,例如计算染色体的GC含量 2 chr ...

  3. HttpRequest Java原生代码封装

    HttpRequest Java原生代码封装  get提交 post提交 name1=value1&name2=value2 的形式  json形式两种形式 package com.beisu ...

  4. 简化业务代码开发:看Lambda表达式如何将代码封装为数据

    摘要:在云服务业务开发中,善于使用代码新特性,往往能让开发效率大大提升,这里简单介绍下lambad表达式及函数式接口特性. 1.Lambda 表达式 Lambda表达式也被称为箭头函数.匿名函数.闭包 ...

  5. ajax代码原理,关于Ajax的原理以及代码封装详解

    前言 其实AJAX内部实现并不麻烦,主要通过一个叫XMLHttpRequest的对象,而这个对象在现有的浏览器均被支持. 可以说,它是整个AJAX实现的基础,是浏览器用于后台与服务器交换数据的对象,有 ...

  6. java编写一个类book代表教材_java 请通过代码封装,实现如下需求: 编写一个类Book,代表教材:...

    java 请通过代码封装,实现如下需求: 编写一个类Book,代表教材: 关注:191  答案:2  mip版 解决时间 2021-02-01 17:18 提问者万丈深渊 2021-02-01 10: ...

  7. C++代码封装成dll供C#中调用、调用dll无可用源

    C#工程不可以直接调用C++的头文件和Lib库等 所以在程序中C#需要调用的现象,先将C++的东西封装成动态链接库,再调用 若调用dll时显示:无可用源调用,说明导入的DLL路径不对. 静态库和动态库 ...

  8. 他山之石——VBA代码封装

    继续学习VBA! 话说CSDN又改版了啊,这世界天天在变化啊! '1 什么是DLL文件'DLL是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的 ...

  9. 京东jd商品详情API接口(item_get-根据ID取商品详情)代码封装

    item_get-根据ID取商品详情接口 通过代码封装该接口可以拿到商品标题,商品价格,商品促销信息,商品优惠价,商品库存,sku属性,商品图片,desc图片,desc描述,sku图片,sku描述,商 ...

最新文章

  1. php 学习笔记 数组1
  2. flask源码学习-路由的注册与请求处理的过程
  3. 为PHP设置服务器(Apache/Nginx)环境变量
  4. Python3 拼接符+和join效率对比测试
  5. 让DNN为您的手机提供内容
  6. NSCTF-部分题目wp
  7. 远程上传下载文件-Xftp5
  8. 如何给ppt编辑页码_拒绝千篇一律:Word插入“侧边”页码,让文档别具一格!...
  9. influxdb无法实现关联表_InfluxDb专业术语
  10. c语言函数修改指针本身,C语言函数内部改变指针本身
  11. 数据类型的提升(promotion)
  12. [JNI] 开发基础(1) c语言基本类型
  13. HTML的字体10种酷炫效果
  14. 服务器主板支持专用条,AMD专用条又要火了?在H110平台上竟然可以完美使用
  15. 笔记本计算机拆开视频,神州笔记本拆卸全过程图解
  16. Bootstrap3动态添加的元素tooltip不生效
  17. C语言 —— 多维数组
  18. 南京邮电大学微型计算机原理与接口技术实验,南京邮电大学《微机原理与接口技术》上机实验参考答案(四次全).pdf...
  19. pandas下载问题
  20. 2018巅峰极客writeup(Misc)

热门文章

  1. 【华为编程大赛】洞穴逃生
  2. request.getRequestURL()和request.getRequestURI()区别
  3. 在线JSON转HTML,TABLE表格工具
  4. 在线正则表达式可视化工具
  5. information_schema系列五(表,触发器,视图,存储过程和函数)
  6. QTP引用外部脚本路径的设定(二)left函数的使用
  7. keychain 专研
  8. 获取文件夹以及子文件夹里面的所有文件
  9. JavaScript 命名空间
  10. [C#]C#补习——类型和操作符—PART1