详细解读php的命名空间(二)


Posted in PHP onFebruary 21, 2018

一:命名空间里的namespace关键字和__NAMESPACE__常量的运用

PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和namespace关键字。

常量__NAMESPACE__会储存当前命名空间的名字字符串,如果当前是全局非命名空间,则保存的是空字符串。

关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。如果不在当前是全局环境的话,那么显式访问的就是全局限定的元素。

__NAMESPACE__实例:

<?php 
namespace Index\Name{ 
 var_dump(__NAMESPACE__); //打印string(10) "Index\Name" 
 
 function foo($classname){ 
  return __NAMESPACE__.'\\'.$classname; 
 } 
} 
 
namespace{ 
 var_dump(__NAMESPACE__); //打印string(0) "" 
 
 var_dump(Index\Name\foo('ceshi')); //打印string(16) "Index\Name\ceshi" 
} 
?>

namespace实例:

<?php 
namespace Index\Name\Index{ 
 function foo(){ 
  return 2; 
 } 
} 
 
namespace Index\Name{ 
 var_dump(namespace\Index\foo()); //打印2 
 
 function foo(){ 
  return 1; 
 } 
} 
 
namespace{ 
 var_dump(namespace\Index\Name\foo()); //打印1 
} 
?>

二:使用命名空间的别名/导入

命名空间具备允许别名导入以及导入的功能,命名空间导入需使用use关键字,如果还需要设置别名则需要use与as进行配合。

1)导入支持范围:

1:为类名称使用别名
2:为接口名称使用别名
3:为命名空间使用别名
4:5.6以上的php版本,允许函数或者常量使用别名。

2)别名/导入格式

导入格式:use [函数/常量] 命名空间完全限定名[类/接口/函数/常量]
别名导入格式:use [函数/常量] 命名空间完全限定名[类/接口/函数/常量] as 别名

注意:如果没有使用完全限定名的话,也和之前使用命名空间一样,会变成当前命名空间+限定名称来组合出完整的命名空间,所以如果不写完全限定名称,这里一定要多留意组合的结果是否是正确的命名空间。

导入实例:

<?php 
namespace Index\Col\Ads{ 
 
 const INSTANCE='const_val'; 
 
 function functionName(){ 
  return 'function_val'; 
 } 
 
 class className{ 
  static function classv(){ 
   return 'class_val'; 
  } 
 } 
} 
 
namespace Col{ 
 const INSTANCE='const_val_col'; 
 
 function functionName(){ 
  return 'function_val_col'; 
 } 
 
 class className{ 
  static function classv(){ 
   return 'class_val_col'; 
  } 
 } 
} 
 
 
namespace Index{ 
/*引入Index\Col\Ads命名空间*/ 
use \Index\Col\Ads; 
/*读取引入的命名空间的常量*/ 
echo \Index\Col\Ads\INSTANCE.'<br/>'; //打印class_val 
/*读取引入的命名空间的函数*/ 
echo \Index\Col\Ads\functionName().'<br/>'; //打印class_val 
/*读取引入的命名空间的类,接口也是一样的*/ 
echo \Index\Col\Ads\className::classv().'<br/>'; //打印class_val 
 
/*引入常量*/ 
use const \Col\INSTANCE; 
/*读取常量*/ 
echo INSTANCE.'<br/>'; //打印const_val_col 
 
/*引入函数*/ 
use function \Col\functionName; 
/*读取函数*/ 
echo functionName().'<br/>'; //打印function_val_col 
 
/*引入类或者接口*/ 
use \Col\className; 
/*读取类或者接口*/ 
echo className::classv().'<br/>'; //打印classname_val_col 
 
} 
?>

以上的例子里Index的命名空间里写的是完全限定名,Index\Col\Ads如果没有前面的\全局操作符的话,就会变成Index\Index\Col\Ads的命名空间了,一定要注意。

别名导入实例:

<?php 
namespace Index\Col\Ads{ 
 
 const INSTANCE='const_val'; 
 
 const NS='namespace'; 
 
 function functionName(){ 
  return 'function_val'; 
 } 
 
 class className{ 
  static function classv(){ 
   return 'class_val'; 
  } 
 } 
} 
 
 
namespace{ 
/*引入Index\Col\Ads命名空间,并设置别名Ads*/ 
use Index\Col\Ads as Ads; 
 
/*引入Index\Col\Ads命名空间的常量INSTANCE,并设置别名con*/ 
use const Index\Col\Ads\INSTANCE as con; 
 
/*引入Index\Col\Ads命名空间的函数functionName,并设置别名func*/ 
use function Index\Col\Ads\functionName as func; 
 
/*引入Index\Col\Ads命名空间的类className,并设置别名classn,接口的别名设置方式和这个一样*/ 
use Index\Col\Ads\className as classn; 
 
echo Ads\NS.'<br/>'; //打印namespace 
echo con.'<br/>'; //打印const_val 
echo func().'<br/>'; //打印function_val 
echo classn::classv().'<br/>'; //打印class_val 
} 
?>

这个例子里是全局的非命名空间,所以没有全局操作符也不会影响导入的命名空间。

三:特别补充

1:命名空间首字符不能是数字,必须是字母或者是下划线,否则会报出farse error。

2:define在命名空间内设置的常量默认是全局的(例外:一个文件内多个命名空间用括号包起来的方式define默认设置的是该命名空间的常量),所以如果需要命名空间下的常量,需要特别写明在常量名称里,例如define('Index\CON','CON')和define(__NAMESPACE__.'\CON','CON')这两种方式都是设置命名空间下的常量CON。

常量实例:

<?php 
namespace Col; 
/*define默认设置的是全局的常量*/ 
define('CON','globals'); 
 
/*特别声明设立的是当前命名空间下的常量*/ 
define(__NAMESPACE__.'\CON','col'); 
 
/*特别声明设立的是Index命名空间下的常量*/ 
define('Index\CON','index'); 
 
/*全局操作符后直接跟常量名,所以获取到的是全局的常量CON*/ 
var_dump(\CON); //globals 
 
/*没有任何限定,所以获取的是当前命名空间的常量CON*/ 
var_dump(CON); //col 
 
/*全局限定,读取其对应的Col命名空间的常量CON*/ 
var_dump(\Col\CON); //col 
 
/*全局限定,读取其对应的Index命名空间的常量CON*/ 
var_dump(\Index\CON); //index 
?>

3:看到上面的实例,推及到函数及类(接口)就不一样了,在命名空间里设置的函数及类(接口)都是属于该命名空间的内容,不管是不是一个文件多个命名空间大括号里设置的。

函数和类的实例:可以看出在命名空间内的函数和类是属于命名空间的

index.php

<?php 
function foo(){ 
 return 'global'; 
} 
 
class fool{ 
 static function ceshi(){ 
  return 'global'; 
 } 
} 
?>

col.php

<?php 
namespace Col; 
require './index.php'; //如果不引入index.php文件,那么下面的\foo()和\foo::ceshi()都会报fatal error 
 
function foo(){ 
 return 1; 
} 
 
class fool{ 
 static function ceshi(){ 
  return 2; 
 } 
} 
 
var_dump(\foo());   //global 
var_dump(foo());   //打印1 
var_dump(\Col\foo());  //打印1 
 
var_dump(\fool::ceshi());  //global 
var_dump(fool::ceshi());  //打印2 
var_dump(\Col\fool::ceshi()); //打印2 
?>

4:设置命名空间的时候,要注意不要使用php的关键字,例如function、class、abstract之类的,否则会报出parse error。

5:同一个命名空间,不同文件间的使用无须带上命名空间,直接使用函数、常量、类及接口就可以了。

6:一个命名空间的类、常量、接口、函数单独引入另一个命名空间,其中函数、常量、类、接口如果发生了冲突,如果没有用限定词则优先使用单独引入类、常量、接口、函数。

实例:

indext.php

<?php 
namespace Lic; 
 
define(__NAMESPACE__.'\CON',1); 
 
function func(){ 
 echo 1; 
} 
 
class foo{ 
 static function ceshi(){ 
  return 1; 
 } 
}

只引入命名空间

<?php 
namespace Col; 
require './indext.php'; 
use \Lic; 
 
define(__NAMESPACE__.'\CON',2); //设定命名空间的常量必须写明命名空间,否则是全局的常量 
 
function func(){ 
 echo 2; 
} 
 
class foo{ 
 static function ceshi(){ 
  return 2; 
 } 
} 
 
var_dump(CON); //打印2 
var_dump(namespace\CON); //打印2 
 
func(); //打印2 
namespace\func(); //打印2 
 
var_dump(foo::ceshi()); //打印2 
var_dump(namespace\foo::ceshi()); //打印2

如果单独引入类、接口、函数、常量的情况,名称冲突且没有用限定的话优先使用引入的:

<?php 
namespace Col; 
require './indext.php'; 
use \Lic\foo; 
use function \Lic\func; 
use const \Lic\CON; 
 
define(__NAMESPACE__.'\CON',2); //设定命名空间的常量必须写明命名空间,否则是全局的常量 
 
function func(){ 
 echo 2; 
} 
 
class foo{ 
 static function ceshi(){ 
  return 2; 
 } 
} 
 
var_dump(CON); //打印1 
var_dump(namespace\CON); //打印2 
 
func(); //打印1 
namespace\func(); //打印2 
 
var_dump(foo::ceshi()); //打印1 
var_dump(namespace\foo::ceshi()); //打印2

暂时就补充到这里,以后还有后续的再添加。。。

PHP 相关文章推荐
PHP 魔术函数使用说明
May 14 PHP
PHP中将网页导出为Word文档的代码
May 25 PHP
解析如何在PHP下载文件名中解决乱码的问题
Jun 20 PHP
php不允许用户提交空表单(php空值判断)
Nov 12 PHP
php读取excel文件示例分享(更新修改excel)
Feb 27 PHP
PHP多个文件上传到服务器实例
Oct 29 PHP
PHP中使用SimpleXML检查XML文件结构实例
Jan 07 PHP
php超快高效率统计大文件行数
Jul 05 PHP
编写PHP程序检查字符串中的中文字符个数的实例分享
Mar 17 PHP
PHP简单实现上一页下一页功能示例
Sep 14 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
Sep 19 PHP
PHP钩子与简单分发方式实例分析
Sep 04 PHP
详细解读php的命名空间(一)
Feb 21 #PHP
thinkphp5 migrate数据库迁移工具
Feb 20 #PHP
Laravel 5.4.36中session没有保存成功问题的解决
Feb 19 #PHP
自写的利用PDO对mysql数据库增删改查操作类
Feb 19 #PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
Feb 19 #PHP
浅析PHP数据导出知识点
Feb 17 #PHP
PHP 应用容器化以及部署方法
Feb 12 #PHP
You might like
php date()日期时间函数详解
2010/05/16 PHP
fgetcvs在linux的问题
2012/01/15 PHP
Android AsyncTack 异步任务实例详解
2016/11/02 PHP
ThinkPHP 3使用OSS的方法
2018/07/19 PHP
使用PHPExcel导出Excel表
2018/09/08 PHP
laravel框架上传图片实现实时预览功能
2019/10/14 PHP
laravel 解决强制跳转 https的问题
2019/10/22 PHP
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
如何简单地用YUI做JavaScript动画
2007/03/10 Javascript
CSS JavaScript 实现菜单功能 改进版
2008/12/09 Javascript
通过url查找a元素应用案例
2014/04/29 Javascript
javascript如何操作HTML下拉列表标签
2015/08/20 Javascript
Bootstrap table使用方法总结
2017/05/10 Javascript
vue在index.html中引入静态文件不生效问题及解决方法
2019/04/29 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
Vue表单控件数据绑定方法详解
2020/02/05 Javascript
在vue中实现禁止回退上一步,路由不存历史记录
2020/07/22 Javascript
浅谈es6中的元编程
2020/12/01 Javascript
Python实现二分法算法实例
2015/02/02 Python
Python实现字典依据value排序
2016/02/24 Python
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
Python中eval带来的潜在风险代码分析
2017/12/11 Python
Pytorch损失函数nn.NLLLoss2d()用法说明
2020/07/07 Python
PyQt5-QDateEdit的简单使用操作
2020/07/12 Python
Python猫眼电影最近上映的电影票房信息
2020/09/18 Python
Python 图片处理库exifread详解
2021/02/25 Python
多视角3D逼真HTML5水波动画
2016/03/03 HTML / CSS
香港时装购物网站:ZALORA香港
2017/04/23 全球购物
幼儿园教师辞职信
2014/01/18 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
店铺转让协议书(2014版)
2014/09/23 职场文书
优秀班主任材料
2014/12/16 职场文书
2015年防汛工作总结
2015/05/15 职场文书
自书遗嘱范文
2015/08/07 职场文书
企业管理不到位检讨书
2019/06/27 职场文书
HR必备:超全面的薪酬待遇管理方案!
2019/07/12 职场文书