“中国要复兴、富强,必须在开源软件领域起到主导作用,为了国家安全和人类发展,责无旁贷,我们须为此而奋斗”——By:云客
今天有人问起,所以把以前写的一个日记发出来:
试想一下,你即将开发一套大型程序,里面用到了多个人的劳动成果,特别是在MVC模式下加载了很多个函数库或者类库,而每个库都有不同的作者,那么库里面的类名或函数名重名了怎么办?类和函数可是超全局的,在PHP5.3以前的版本中一个php请求由多个文件通过include或者require链接组成的整体逻辑体系处理,这个逻辑空间是一个扁平的整体,类、函数、常量的作用域在里面畅通无阻;而开发者是这个世界的唯一上帝,有能力通过命名的方式避免冲突,倒也相安无事,但随着项目大了一个开发者忙不过来了,多个开发者开始协同开发,那这个逻辑空间里面就有多个上帝了,一个好的类、函数、常量名字大家都不约而同的想到,因为他们畅通无阻的作用域便发生了冲突,上帝都是平等的,总不能我用好名字你就不许用吧,得公平解决此事,于是名字空间诞生了。约定谁编写入口主文件那这个世界就是谁的,其他的上帝给自己的地盘画个圈,一切为了给请求服务,要到哪个上帝那取点东西用用就先到找到他的地盘再说,好了下面开始讲解用法:
名字空间于php5.3版本开始启用,目的是为了解决名字冲突,在任何需要使用的代码之前申明命名空间,格式如下:namespace MyProject; 注意:没有引号,以分号结束,关键词namespace大小写均可,前面不能有除用于定义源文件编码方式的 declare 语句之外的任何语句,文件中<?php之前也不能有包括空字符的任何内容,但在<?php与定义语句之间可以有注释、换行、空格;php的执行可以从任意命名空间开始,而不一定非得全局空间,只有类、接口、函数和常量这几种类型的代码受其影响,名字空间以字母开头加数字命名,不区分大小写,定义多层次的名字空间每层之间用\分割(不能用/或者点号,开头不用加\);同一个命名空间可以定义在多个文件中(即多文件共享同一个名字空间);在同一个文件中也可以定义多个名字空间,有两种语法:namespace MyProject;或者namespace MyProject{代码} 注意}后面没有分号;当将名字空间里的代码和非名字空间里面的代码组合在一个文件时,只能用后一种方式,定义全局空间时无需给出名字;常量__NAMESPACE__的值是当前命名空间的名字,全局空间时为空字符;namespace关键字除申明命名空间外,还可以用在名字空间路径里面作为当前名字空间使用,相当于类里面的SELF。
用use关键词来为名字空间或类、函数、常量进行导入及取别名:
导入名字空间use Zend\Stdlib\myspace as yunke;意思是导入名字空间Zend\Stdlib\myspace并取别名为yunke。如果省略as相当于use Zend\Stdlib\ myspace as myspace;注意这里use后面的路径必须是完全限定空间(绝对路径),从全局空间开始的(前面的\可以不加),同一个名字空间可有多个别名;导入和取别名可以针对名字空间或类,不能为函数或常量(在5.6+中已经可以使用“use function”和“use const”关键词来为函数和常量导入和取别名);
use yunke;可以是导入全局空间的一个叫yunke的类,也可以是导入命名空间yunke,如果条件存在可以两者均是。
use a\b\c as x; x\fun(); 执行a\b\c\fun();
use a\b as x; x\c\fun(); 执行a\b\c\fun();
use b\c as x; a\x\fun(); 并不执行a\b\c\fun(); 说明别名不可嵌套使用,只能用于调用路径的开始。
use语句在命令行下不工作;如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。调用时在名称前加上前缀 \ 表示该名称是全局空间中的名称。当 PHP 遇到一个非限定的类、函数或常量名称时,类被解析为当前空间的类,函数和常数如果在当前空间没有发现便使用全局空间的,如果类、函数、常量的名称是动态产生的话(如$a=’yunke’;$a();)赋值给$a的字符串必须是完全限定的名字空间,它是从全局空间开始的,并非当前空间或相对当前空间的子空间,因为相对解析是在编译时完成,在运行时已经全部解析为完全限定名字空间了,所以赋值给$a的字符串必须是完全限定的名字空间,既然如此$a的值带不带前导的\就无所谓了,一般不带,所以必须指明名字空间;
define();默认定义的常量是全局空间的,如果要定义某名字空间的常量需要在名字前面加路径,
交流互动