PHP关键特性之命名空间实例详解


Posted in PHP onMay 06, 2017

命名空间主要是为了解决代码中类和函数可能存在冲突的问题,而这个特性其他语言一早就有,PHP则是姗姗来迟,它的出现催生了 PSR-4 的诞生,从而也催生了 Composer 的兴起,所以是非常重要的特性。

命名空间的定义

命名空间是一个容器,这个容器主要是为了识别其下的类和函数。一旦定义了命名空间,它下面的代码就属于这个命名空间了,所以命名空间的定义要在代码的最开始行。

对于同一个包来说,同一个命名空间或者子命名空间的代码没有必要在一个 PHP 文件中定义,子命名空间下的代码是为了完成特定模块的工作,组合起来就是一个包完整的命名空间。

假如编写的代码没有定义命名空间,那说明它属于全局的命名空间(\ 符号),所以能够直接引用类或者函数(不用添加 \ 符号)。

引用命名空间标识符的三种方式

(1)Fully-qualified name

类似于操作系统上的绝对路径,而且是完整的路径,所以在理解的时候不会有误解。

比如在 new \A\B\C ,那么 C 就被会解析到 A\B 命名空间下的 C 类。

(2)Qualified name

类似于操作系统上的相对路径,它包含部分名字并被引用到当前的命名空间。

比如 B\C() 在命名空间 A 下调用,则最终引用的命名空间就是 A\B\C()。

(3)Unqualified name

类似于Qualified name,但是没包括子命名空间。

比如 C() 在命名空间 A\B 下调用,则最终引用的命名空间就是 A\B\C()。

通过一个例子来说明三种引用方式:

namespace \Example;
require_once "fnction.php";
class ClassA {}
function Function() {}
//完全限定名称
\Example\Function();
\Example\B\Function(); 
//限定名称
B\Function(); //指向 \Example\B\Function();
//非限定名称
$test = new ClassA(); //resolves to \Example\ClassA
Function(); //指向 \Example\Function

注意:

•Inside a namespace,假如在 current scope 没有发现函数和常量的定义,PHP 不会报错。而是去全局命名空间中寻找。

•Inside a namespace,假如在 current scope 没有发现类的定义,则 PHP 会直接报错,不会去全局域中找对应的类,所以假如你需要引用一个 internal 或用户自定义的类,必须使用完全限定名称。

先举个简单的例子,首先编写一段代码(定义在命名空间下),命名为 function.php :

namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() 
{
  return "foo\r\n";
}
class foo 
{
  static function staticmethod()
  {
    return __METHOD__ . "\r\n" ;
  }
  function foofunction()
  {
    return __METHOD__ . "\r\n" ;
  }
}

再编写一段代码 test.php,也是处于命名空间之下的代码:

namespace secondsp;
include 'function.php';
class foo
{
  function foofunction()
  {
    return __METHOD__ . "\r\n" ;
  }
}
function is_file($file)
{
  return true ;
}
//非限定名称:实例化secondsp\foo类对象
$obj = new foo; 
echo $obj->foofunction();
//实例化Foo\Bar\subnamespace\foo 类对象
$obj = new Foo\Bar\subnamespace\foo ;
echo $obj->foofunction();
//代码会报错,在命名空间内部,假如无法找到当前命名空间下的类,则会报错
//$obj = new ArrayObject(array(1)); 
$obj = new \ArrayObject(array(1)); 
//在命名空间内部,假如无法找到当前命名空间下的函数或者常量,则会寻找 native function
echo strlen("nihao");
 //引用当前命名空间下的函数
var_dump(is_file('nihao')); //True
//引用全局函数
var_dump(\is_file('nihao')); //False

导入,别名

假如要使用的命名空间层级很长且数量很多,那么在使用的时候特别麻烦,所以可以使用 use 关键字导入命名空间、类、常量、函数等,然后可以使用它们直接引用完整的名称。而 alias 关键字可以给导入的类和函数等重命名。

举个例子如何使用 use 关键字,该代码处于全局命名空间之下:

include 'function.php';
use Foo\Bar\subnamespace\foo ;
$obj = new foo;
echo $obj->foofunction();
use Foo\Bar\subnamespace\foo as aliasfunname;
$obj = new aliasfunname;
echo $obj->foofunction();
use Foo\Bar\subnamespace ; 
$obj = new subnamespace\foo ;
echo $obj->foofunction();
use Foo\Bar\subnamespace as aliasname;
$obj = new aliasname\foo ;
echo $obj->foofunction();
//由于调用代码并不在命名空间内,所以对于全局的类,无需引入使用
$obj = new ArrayObject(array(1)); 
//导入一个函数
use function Foo\Bar\subnamespace\foo  ;
echo foo();
use function Foo\Bar\subnamespace\foo as func;
echo func();
use const Foo\Bar\subnamespace\FOO;
//echo FOO;

总结:

•和 Python 不一样,PHP 中的命名空间是语义上的一种概念,和具体代码的位置、布局没有关系,换句话说,使用命名空间的代码需要自己引入库文件(所有文件),至于库文件如何组织无所谓;而在 Python 中,假如模块或包中有一个 __init__.py 文件,则 Python 解析器会自动引入包或所有模块的文件。

•PHP 中作用域的概念很弱化,全局域和局部域分的很清楚,比如在函数或类中无法引用全局空间中的变量。而在命名空间则不同,定义命名空间的代码,假如找不到对应命名空间下的常量和函数,则会使用全局的常量和函数;而假如找不到对应名命名空间下的类(包括自定义类),则代码直接报错。

•通过 use 关键字使用命名空间的,无须通过完全限定名称的方式(\ 符号)导入,因为 PHP 已经假设导入的是完全限定的命名空间。

•通过 use 关键字可以导入常量、函数、类、接口、其他命名空间。

•命名空间是一种语言特性,为了追求更有效的使用,应该有一种使用规范和自动加载机制,这就是 PSR-4 规范。

以上所述是小编给大家介绍的PHP关键特性之命名空间实例详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

PHP 相关文章推荐
Smarty Foreach 使用说明
Mar 23 PHP
PHP随机数生成代码与使用实例分析
Apr 08 PHP
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
May 24 PHP
PHP中call_user_func_array()函数的用法演示
Feb 05 PHP
PHP 如何利用phpexcel导入数据库
Aug 24 PHP
PHP的foreach中使用引用时需要注意的一个问题和解决方法
May 29 PHP
php数字运算验证码的实现代码
Jul 30 PHP
提高php编程效率技巧
Aug 13 PHP
PHP如何获取当前主机、域名、网址、路径、端口等参数
Jun 09 PHP
PHP设计模式之工厂模式定义与用法详解
Apr 03 PHP
PHP中实现中文字串截取无乱码的解决方法
May 29 PHP
PHP中的empty、isset、isnull的区别与使用实例
Mar 22 PHP
PHP 中使用explode()函数切割字符串为数组的示例
May 06 #PHP
Thinkphp 空操作、空控制器、命名空间(详解)
May 05 #PHP
thinkPHP实现的联动菜单功能详解
May 05 #PHP
thinkPHP实现的省市区三级联动功能示例
May 05 #PHP
php str_replace替换指定次数的方法详解
May 05 #PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
May 05 #PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
May 05 #PHP
You might like
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
PHP第三方登录―QQ登录实现方法
2017/02/06 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
双击滚屏-常用推荐
2006/11/29 Javascript
js 文件引入实现代码
2010/04/23 Javascript
javascript中的关于类型转换的性能优化
2010/12/14 Javascript
JS自调用匿名函数具体实现
2014/02/11 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
2017/02/09 Javascript
js中数组插入、删除元素操作的方法
2017/02/15 Javascript
整理一些最近经常遇到的前端面试题
2017/04/25 Javascript
React diff算法的实现示例
2018/04/20 Javascript
Angular6使用forRoot() 注册单一实例服务问题
2019/08/27 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
[47:50]Secret vs VP 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
[42:20]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python分割文件的常用方法
2014/11/01 Python
python3 flask实现文件上传功能
2020/03/20 Python
对python实时得到鼠标位置的示例讲解
2018/10/14 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
Python Excel处理库openpyxl使用详解
2019/05/09 Python
python读取dicom图像示例(SimpleITK和dicom包实现)
2020/01/16 Python
豆腐の盛田屋官网:日本自然派的豆乳面膜、肥皂、化妆水、乳液等
2016/10/08 全球购物
马耳他航空公司官方网站:Air Malta
2019/05/15 全球购物
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
2014年自愿离婚协议书范本
2014/09/25 职场文书
地方课程教学计划
2015/01/19 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书
扩展多台相同的Web服务器
2021/04/01 Servers
日本动漫十大公认神作:第五现已全网禁播,《死亡笔记》在榜
2022/03/18 日漫
Python 全局空间和局部空间
2022/04/06 Python