资讯专栏INFORMATION COLUMN

php命名空间简介

cangck_X / 990人阅读

摘要:全局命名空间接触过系统的同学都应该知道根目录吧,我们可以将全局命名空间想象为的根目录,在该目录下存放的都是本身提供的各种接口类函数常量。

以下是我对命名空间的一些体会和理解,最好先看下php的官方文档再来看此文,会更好一点。由于水平有限,文中如有纰漏,希望指出

前言

在php5.3以上的版本中,php引入了命名空间(以下称呼为namespace)这个性能。个人认为,这是非常重要的一项改变。之所以说重要,并不是说namespace本身有多么牛逼或者多高的技术含量。而是由于命名空间的引入,引起了一些列的连锁反应,这些连锁反应给我们现在phper开发者提供了另一种可能。

现在的开发方式


我们在以往开发应用的时候,即使是非常简单的应用,也经常使用php的那些框架,他们通常很重、很大、很难学,更要命的是,还很多,什么Yii2、Thinkphp、CI、ZendFrame、Laravel......好吧我不想说了。

另一种可能


现在呢,我们似乎有了另外一种选择。依靠composer包管理工具,加载packagist上面那些优秀的组件,然后通过composer提供的自动加载机制,将组建应用到项目中去。我们的开发似乎变成了摆积木,我们要做的事情只是将组件恰当的组合起来,怎么样,听着是不是很心动是么?全世界优秀的轮子随我用,这个feel倍爽!!!哦,离题有点远了,那么这和本文的主题namespacey又有什么关系呢?当然有关系了,自动加载的基石namespace

实现另外一种可能很重要的一步就是,将packagist组件自动加载到应用中。由于php的_autoload有各种各样的实现方式,为此php-fig(php framework interop group一个php组织)提出了psr-0(已经废弃)和psr-4,这两个专门自动加载的解决方案,其核心思想就是:将命名空间和实际的磁盘物理路径建立映射

(ps : 到目前为止spr-0、spr-4只是推荐的自动加载解决方案,并没有强制,但事实上,基本都采用了这种自动加载方式。除了spr-和spr-4外,composer还支持file 和classmap的方式)

为什么会有命名空间,它解决了什么问题?

命名空间出现的根本原因是为了解决命名冲突的问题,个人认为主要是为了解决以下命名冲突


用户自定义的接口/类/trait/函数/常量 同 php系统提供的 接口/类/trait/函数/常量命名冲突

用户自定义的接口/类/trait/函数/常量 同 第三方框架提供的 接口/类/trait/函数/常量命名冲突

举个例子


我们经常使用var_dump进行断点调试,这个是系统提供给我们的内置函数。但是呢,有的程序员对var_dump输出的数据格式不是很满意,希望自己写一个var_dump函数(var_dump用时间长了,叫其他的名字不习惯),自己格式化其输出信息,但是报错!

========================================
" echo $message; echo "
========================================
" } /** * 报错信息:PHP Fatal error: Cannot redeclare var_dump() */
命名空间的一些基础概念?

我将采用类比的方法来说明这些高深的概念,尽量能让大家清楚。

全局命名空间


接触过linux系统的同学都应该知道根目录"/"吧,我们可以将全局命名空间想象为linux的根目录,在该目录下存放的都是php本身提供的各种接口/类/trait/函数/常量。

完全限定名称


以全局命名空间为前缀的名称,例如, $a = new currentnamespacefoo(); 或 currentnamespacefoo::staticmethod();我们可以将其类比为绝对路径

限定名称


不以全局命名空间为前缀的名称,例如,$a = new subnamespacefoo();或subnamespacefoo::staticmethod();我们可以将其类比为相对路径

非限定名称


不包含任何前缀的名称,例如, $a=new foo(); 或 foo::staticmethod();我们可以将其类比一个问文件名称或者目录名称

php中的那些要素会受到命名空间的影响?

首先肯定一点,并不是所有的元素都受到命名空间的影响,比如说变量就不会,只有以下php要素会受到影响:

类(class)

接口(interface)

trait

常量(constant)

方法名(function,我认为object里面的方法是method)

什么是别名/导入?命名空间的解析规则是什么?两者又有什么关系? 什么是别名/导入?

我们可以认为别名/导入,类似是windows下的快捷方式或者是linux下的软链,通过该快捷方式我们可以链接到,别的空间下的class、interface、trait、constant、function,甚至可以是单纯的连接到别的命名空间而不特指该空间下的任何元素。下面举个例子

当我们的代码中有以别名打头的情况时,php就会尝试链接到别名对应的命名空间中的元素,或是别名对应的命名空间,然后拼接剩余的名称,如果有的话。例子中NSnamesubnsfunc(); 检查到NSname是别名,所以先链接到MyFullNSname, 然后拼接剩余名称MyFullNSnamesubnsfunc();

(ps:导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析,前导的反斜杠是不必要的也不推荐的)

命名空间的解析规则是什么?

一图胜千言,还是上图吧

从图中,可以看出主要是从完全限定名和非完全限定名这两块进行分析的。

两者的关系是什么?

由上图,我们可以知道,限定名称和非限定名称的解析都会受到别名的影响。
而且,别名的优先级比当前命名空间的优先级高(很多地方都没有说)
也就是说,在一个命名空间下,限定名称和非限定名称会先尝试寻找别名替换,如果找不到对应的别名,才会将当前的命名空间追加到现在的名字前面组成完全限定名

Test();

a.php和b.php两个文件在同一个目录下:在b.php文件中,在namespace Top下面,拥有别名TestTop as Top,所以new TopB() 会被解释成 new TestTopB(),也就是将别名进行了替换; 而并不是new TopTopB(),将当前空间名添加到现在的名字前面。所以此时的运行结果是:xxxx/b.php

命名空间的一些易错点,仅个人体会

1、class 、interface 、traits和const 、function尝试执行的加载策略不同

2、一个文件中,只有第一个namespace声明命名空间前不能有任何字符,特别是bom头(看不见但是存在),其他的namespace不做限制。

3、namespace本身并不分区大小写,相同名字的namespace认为是同一个空间


参考资料

http://php.net/manual/zh/lang...
《Modern php》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21697.html

相关文章

  • PHP 扩展开发】Zephir 简介

    摘要:什么是是一种中间语言,以接近的语法来编写代码,然后转换编译成扩展,旨在简化扩展的创建和可维护性。如果成功,会自动生成文件到目录你需要编辑填加扩展测试一下就这样,你也会扩展开发了附附编译扩展的方法 什么是 Zephir Zephir 是一种中间语言,以接近 PHP 的语法来编写代码,然后转换编译成 PHP 扩展,旨在简化 PHP 扩展的创建和可维护性。利用编译来提高性能和资源消耗,又不需...

    arashicage 评论0 收藏0
  • Typecho Framework: Hello world!

    摘要:是所用的框架,本文将介绍如何用这个框架写一个程序。在目录下建立目录,并在其中创建文件首先我们定义一个命名空间,我们的程序使用为命名空间。入口程序这样基本上就完成了。会自动在目录下找模板文件,约定大于配置。 Typecho Framework是SegmentFault所用的框架,本文将介绍如何用这个框架写一个Hello World程序。如果你不了解Typecho Framework,请先...

    fish 评论0 收藏0
  • Phalcon入门教程之目录结构

    摘要:原文发表于入门教程之目录结构很多初学的朋友,对于以框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。只需要通过注册这些目录结构,即可正常使用。 原文发表于:Phalcon入门教程之目录结构 很多初学Phalcon的朋友,对于以Phalcon框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。比如多模块的项目中,如何共用libs类库和models目录中模型类的情况,就有很...

    reclay 评论0 收藏0
  • Composer管理PHP依赖关系

    摘要:然而各自为政的打包方式依赖关系的处理,导致了很难将两个开源项目集成到一起。虽然有这种官方支持的包管理工具,但是依然没有很好的统一的依赖关系管理的办法。项目编译和打包依赖关系的解决都可以很轻松的实现。 简介 现在软件规模越来越大,PHP项目的开发模式和许多年前已经有了很大变化。记得初学PHP那会儿,boblog是一个很好的例子,几乎可以代表PHP项目的开发模式。当时PHP 5.x以上的版...

    Mertens 评论0 收藏0
  • composer

    摘要:自动加载为了实现类的随取随用,类的命名空间定义建议遵从一定的规则。这种规则可以是某一项目组约定的。不过为了使得类库统一,项目指定了一种命名空间的规范,被一些流行项目采用。用来指定在软件包级别上区别。注意默认类库是使用规范自动加载的。 简介 composer是一个php中管理依赖的工具。它使你可以在项目中声明用到的包/库,之后它会自动安装相关包。 Composer is not a ...

    Miyang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<