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 相关文章推荐
PHP Smarty生成EXCEL文档的代码
Aug 23 PHP
PHP 定界符 使用技巧
Jun 14 PHP
基于PHP服务端图片生成缩略图的方法详解
Jun 20 PHP
PHP命名空间(namespace)的使用基础及示例
Aug 18 PHP
jQuery Mobile + PHP实现文件上传
Dec 12 PHP
php中header设置常见文件类型的content-type
Jun 23 PHP
PHP在线调试执行的实现方法(附demo源码)
Apr 28 PHP
php 数组处理函数extract详解及实例代码
Nov 23 PHP
PHP 二维关联数组根据其中一个字段排序(推荐)
Apr 04 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 PHP
[原创]PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】
Jul 12 PHP
php7连接MySQL实现简易查询程序的方法
Oct 13 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
PHP实现文件下载详解
2014/11/27 PHP
PHP列出MySQL中所有数据库的方法
2015/03/12 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
PHP封装XML和JSON格式数据接口操作示例
2019/03/06 PHP
YII2.0框架行为(Behavior)深入详解
2019/07/26 PHP
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
jQuery实时显示鼠标指针位置和键盘ASCII码
2016/03/28 Javascript
Vue项目中quill-editor带样式编辑器的使用方法
2017/08/08 Javascript
jsonp跨域获取数据的基础教程
2018/07/01 Javascript
浅谈 Webpack 如何处理图片(开发、打包、优化)
2019/05/15 Javascript
Vue学习之常用指令实例详解
2020/01/06 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
2020/03/25 Javascript
python自动化测试之setUp与tearDown实例
2014/09/28 Python
python入门基础之用户输入与模块初认识
2016/11/14 Python
pandas 选择某几列的方法
2018/07/03 Python
python读写csv文件实例代码
2019/07/05 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
Python实现RabbitMQ6种消息模型的示例代码
2020/03/30 Python
pycharm实现print输出保存到txt文件
2020/06/01 Python
Pytorch实现将模型的所有参数的梯度清0
2020/06/24 Python
详解python 条件语句和while循环的实例代码
2020/12/28 Python
解决pycharm 格式报错tabs和space不一致问题
2021/02/26 Python
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
英国办公用品商店:Office Outlet
2018/04/04 全球购物
美国迪克体育用品商店:DICK’S Sporting Goods
2018/07/24 全球购物
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
Nike香港官网:Nike HK
2019/03/23 全球购物
Prototype中如何为一个元素添加一个方法
2014/12/08 面试题
冰淇淋开店创业计划书
2014/02/01 职场文书
科研课题实施方案
2014/03/18 职场文书
节水口号标语
2014/06/19 职场文书
MySQL 不等于的三种使用及区别
2021/06/03 MySQL