[TOC]
* * * * *
## 1 命名空间的意义(参考php官方手册编写)
>[info] 1 命名空间的作用
声明php中类名,函数名,常量名这三类符号命名范围
>[info] 2 命名空间的引入
在**php5.3引入命名空间之前**,上述三类符号的命名范围是**全局空间**,在大型工程项目中,容易出现**符号命名重复冲突**。
为了解决大型工程项目的符号命名冲突问题,在**php5.3中引入命名空间**的支持。
**因此命名空间是用来声明类名,函数名,常量名三类符号命名范围**
>[info] 3 其他符号名作用范围分析
**预定义变量**的作用范围 在全局空间。通常前置$_符号
`$GLOBALS $_SERVER $_GET`
**普通变量**的作用范围 在当前大括号限制的局部空间中。通常前置$符号
~~~
if(){}
while(){}
funciont(){}
class xx{}
~~~
* * * * *
## 2 命名空间的简单使用
>[info] 1 命名空间的声明
**关键字 namespae test;**
声明当前命名空间为test,限制其后三类符号的作用域
* * * * *
example1: 命名空间的声明方法
~~~
<?php
namespace MyProject ;
const CONNECT_OK = 1 ;
class Connection { /* ... */ }
function connect () { /* ... */ }
?>
~~~
* * * * *
需要注意的是namespace 必须在当前文件的第一行。
example2: 命名空间的错误使用
~~~
<html>
<?php
namespace MyProject ;
// 致命错误 - 命名空间必须是程序脚本的第一条语句
?>
~~~
>[info] 2 命名空间的符号使用
**`__NAMESPACE__ ` 当前命名空间名称**
example3: `__NAMESPACE__ `命名空间中使用
~~~
<?php
namespace MyProject ;
echo '"' , __NAMESPACE__ , '"' ;
// 输出 "MyProject"
?>
~~~
* * * * *
不包含命名空间的的全局空间输出空字符串
example4:`__NAMESPACE__ `非命名空间中使用
~~~
<?php
echo '"' , __NAMESPACE__ , '"' ;
// 输出 ""
?>
~~~
* * * * *
**namespace 当前命名空间名称使用,相当于self操作符**
example5:命名空间中namespae的使用
~~~
<?php
namespace MyProject ;
// 调用函数 MyProject\blah\mine()
namespace\ blah \ mine ();
// 调用函数 MyProject\func()
namespace\ func ();
// 调用函数 MyProject\sub\func()
namespace\ sub \ func ();
// 调用MyProject\cname类的静态方法method
namespace\ cname :: method ();
// 实例化MyProject\sub\cname类的对象
$a = new namespace\ sub \ cname ();
// 将常量MyProject\CONSTANT赋值给$b
$b = namespace\ CONSTANT ;
?>
~~~
* * * * *
不包含命名空间的全局空间,使用全局符号名
example6: 非命名空间中namespace的使用
~~~
<?php
namespace\ func ();
// 调用函数 func()
namespace\ sub \ func ();
// 调用函数 sub\func()
namespace\ cname :: method ();
// 调用类cname的静态方法method
$a = new namespace\ sub \ cname ();
// 实例化类sub\cname对象
$b = namespace\ CONSTANT ;
// 将常量CONSTANT赋值给$b
?>
~~~
>[info] 3 类名的引用
**1-1不带前缀:非命名空间**
~~~
<?php
$a=new foo();
foo::staticmethod();。
?>
~~~
foo 将被解析为 foo
* * * * *
**1-2不带前缀:带有命名空间**
~~~
<?php
namespace currentnamespace;
$a=new foo();
foo::staticmethod();。
?>
~~~
foo 将被解析为 currentnamespace\foo
* * * * *
**2-1非反斜杠开头的前缀:不带命名空间**
~~~
<?php
$a = new subnamespace\foo();
subnamespace\foo::staticmethod();
?>
~~~
foo 会被解析为subnamespace\foo
* * * * *
**2-2非反斜杠开头的前缀:带命名空间**
~~~
<?php
namespace currentnamespace
$a = new subnamespace\foo();
subnamespace\foo::staticmethod();
?>
~~~
foo 会被解析为 currentnamespace\subnamespace\foo
**3 以反斜杠开头的前缀:命名空间或非命名空间中**
~~~
<?php
$a = new \currentnamespace\foo();
\currentnamespace\foo::staticmethod();
?>
~~~
foo 总是被解析为全局符号currentnamespace\foo。
>[info] 4 函数与常量名的引用
如果当前命名空间不存在。会使用全局空间中的函数和常量名称
~~~
<?php
namespace A \ B \ C ;
const E_ERROR = 45 ;
function strlen ( $str )
{
return \strlen ( $str ) - 1 ;
}
echo E_ERROR , "\n" ;
// 输出 "45"
echo INI_ALL , "\n" ;
// 输出 "7" - 使用全局常量 INI_ALL
echo strlen ( 'hi' ), "\n" ;
// 输出 "1"
if ( is_array ( 'hi' )) {
echo "is array\n" ;
} else {
echo "is not array\n" ;
}
// 输出 "is not array"
?>
~~~
>[info] 5 非命名空间与命名空间的元素
非命名空间元素到命名空间元素必须使用完全限定名称,**前面需要使用反斜杠**
如果使用**变量表示(动态)**的类名,函数名或常量名,
限定名称和完全限定名称没有区别,因此**其前导的反斜杠是不必要的**。
example7:命名空间限定
~~~
example7_1.php:
<?php
class classname
{
function __construct ()
{
echo __METHOD__ , "\n" ;
}
}
function funcname ()
{
echo __FUNCTION__ , "\n" ;
}
const constname = "global" ;
$a = 'classname' ;
$obj = new $a ; // prints classname::__construct
$b = 'funcname' ;
$b (); // prints funcname
echo constant ( 'constname' ), "\n" ; // prints global
?>
~~~
~~~
example7_2.php:
<?php
namespace namespacename ;
class classname
{
function __construct ()
{
echo __METHOD__ , "\n" ;
}
}
function funcname ()
{
echo __FUNCTION__ , "\n" ;
}
const constname = "namespaced" ;
include 'example7_1.php' ;
$a = 'classname' ;
$obj = new $a ;
// 输出 classname::__construct
$b = 'funcname' ;
$b ();
// 输出 funcname
echo constant ( 'constname' ), "\n" ;
// 输出 global
~~~
~~~
/* 双引号会对反斜杠\进行转义,因此需要使用
"\\namespacename\\classname" 表示命名空间的限定 */
$a = '\namespacename\classname' ;
$obj = new $a ;
// 输出 namespacename\classname::__construct
$a = 'namespacename\classname' ;
$obj = new $a ;
// 输出 namespacename\classname::__construct
$b = 'namespacename\funcname' ;
$b ();
// 输出 namespacename\funcname
$b = '\namespacename\funcname' ;
$b ();
// 输出 namespacename\funcname
echo constant ( '\namespacename\constname' ), "\n" ;
// 输出 namespaced
echo constant ( 'namespacename\constname' ), "\n" ;
// 输出 namespaced
?>
~~~
>[info] 6 全局空间
如果没有定义命名空间,所有的类与函数定义在全局空间。
名称前加上前缀\表示该名称是全局命名空间中的名称。
example8:
~~~
<?php
namespace A \ B \ C ;
/* 这个函数是 A\B\C\fopen */
function fopen () {
// 调用全局的fopen函数
$f = \fopen (...);
return $f ;
}
?>
~~~
## 3 命名空间的别名与导入
**关键字use test**
可以用来定义命名空间与类的别名
* * * * *
example8:使用use操作符导入/使用命名空间与类别名.
~~~
<?php
namespace foo ;
use My\Full\Classname as Another ;
// 等价于 use My\Full\NSname as NSname
use My\Full\NSname ;
// 导入一个全局类
use \ArrayObject ;
$obj = new namespace\ Another ;
// 实例化 foo\Another 对象
$obj = new Another ;
// 实例化 My\Full\Classname 对象
NSname \ subns \ func ();
// 调用函数 My\Full\NSname\subns\func
$a = new ArrayObject (array( 1 ));
// 实例化 ArrayObject 对象
?>
~~~
* * * * *
example9: 通过use操作符导入/使用别名,
一行中包含多个use语句
~~~
<?php
use My \ Full \ Classname as Another , My \ Full \ NSname ;
$obj = new Another ;
// 实例化 My\Full\Classname 对象
NSname \ subns \ func ();
// 调用函数 My\Full\NSname\subns\func
?>
~~~
* * * * *
>[danger] 1 函数与常量不可以使用use定义别名
>[danger] 2 导入操作是在编译时执行的。
使用变量表示(动态)的类名,函数名称或常量名称则是运行时执行的
~~~
<?php
use My \ Full \ Classname as Another , My \ Full \ NSname ;
$obj = new Another ;
// 实例化一个 My\Full\Classname 对象
$a = 'Another' ;
$obj = new $a ;
// 实际化一个 Another 对象
?>
~~~
>[danger] 3 导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
example10 导入完全限定名称
~~~
<?php
use My \Full\Classname as Another , My\Full\NSname ;
$obj = new Another ;
// 实例化My\Full\Classname的对象
$obj = new \Another ;
// 实例化Another类的对象
$obj = new Another\thing ;
// 实例化类My\Full\Classname\thing的对象
$obj = new \Another \ thing ;
// 实例化类Another\thing的对象
?>
~~~
## 4 名称解析规则总结
>[info] 1 命名空间名称定义
非限定名称Unqualified name
名称中不包含命名空间分隔符的标识符,例如 Foo
限定名称Qualified name
名称中含有命名空间分隔符的标识符,例如 Foo\Bar
完全限定名称Fully qualified name
名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,
例如 \Foo\Bar。 namespace\Foo 也是一个完全限定名称。
>[info] 2 名称解析遵循下列规则:
1. 对完全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。
2. 所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()。
3. 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。
4. 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。
5. 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的: 1. 在当前命名空间中查找名为 A\B\foo() 的函数
2. 尝试查找并调用 全局(global) 空间中的函数 foo()。
6. 在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析: 1. 在当前命名空间中查找A\B\C类。
2. 尝试自动装载类A\B\C。
new D\E()的解析: 1. 在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。
2. 尝试自动装载类 A\B\D\E。
为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()。
>[info] 3 示例
example 11 名称解析规则
~~~
<?php
namespace A ;
use B \ D , C \ E as F ;
// 函数调用
foo ();
// 首先尝试调用定义在命名空间"A"中的函数foo()
// 再尝试调用全局函数 "foo"
\foo ();
// 调用全局空间函数 "foo"
my \ foo ();
// 调用定义在命名空间"A\my"中函数 "foo"
F ();
// 首先尝试调用定义在命名空间"A"中的函数 "F"
// 再尝试调用全局函数 "F"
~~~
~~~
// 类引用
new B (); // 创建命名空间 "A" 中定义的类 "B" 的一个对象
// 如果未找到,则尝试自动装载类 "A\B"
new D (); // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
// 如果未找到,则尝试自动装载类 "B\D"
new F (); // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
// 如果未找到,则尝试自动装载类 "C\E"
new \ B (); // 创建定义在全局空间中的类 "B" 的一个对象
// 如果未发现,则尝试自动装载类 "B"
new \ D (); // 创建定义在全局空间中的类 "D" 的一个对象
// 如果未发现,则尝试自动装载类 "D"
new \ F (); // 创建定义在全局空间中的类 "F" 的一个对象
// 如果未发现,则尝试自动装载类 "F"
~~~
~~~
// 调用另一个命名空间中的静态方法或命名空间函数
B \ foo (); // 调用命名空间 "A\B" 中函数 "foo"
B :: foo (); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
// 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"
D :: foo (); // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
// 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"
\ B \ foo (); // 调用命名空间 "B" 中的函数 "foo"
\ B :: foo (); // 调用全局空间中的类 "B" 的 "foo" 方法
// 如果类 "B" 未找到,则尝试自动装载类 "B"
~~~
~~~
// 当前命名空间中的静态方法或函数
A \ B :: foo (); // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"
\ A \ B :: foo (); // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"
?>
~~~
## 5 总结
>[info] 1 命名空间的意义
声明类,函数,常量名的命名空间,防止命名冲突。
>[info] 2 命名空间的简单使用
命名空间中符号名称的使用方法
>[info] 3 命名空间的别名与导入
命名空间中类的别名使用方法
>[info] 4 命名空间名称解析规则
根据前缀解析
- 更新记录
- 概述
- 文件索引
- 函数索引
- 章节格式
- 框架流程
- 前:章节说明
- 主:(index.php)入口
- 主:(start.php)框架引导
- 主:(App.php)应用启动
- 主:(App.php)应用调度
- C:(Controller.php)应用控制器
- M:(Model.php)数据模型
- V:(View.php)视图对象
- 附:(App.php)应用启动
- 附:(base.php)全局变量
- 附:(common.php)模式配置
- 附:(convention.php)全局配置
- 附:(Loader.php)自动加载器
- 附:(Build.php)自动生成
- 附:(Hook.php)监听回调
- 附:(Route.php)全局路由
- 附:(Response.php)数据输出
- 附:(Log.php)日志记录
- 附:(Exception.php)异常处理
- 框架工具
- 另:(helper.php)辅助函数
- 另:(Cache.php)数据缓存
- 另:(Cookie.php)cookie操作
- 另:(Console.php)控制台
- 另:(Debug.php)开发调试
- 另:(Error.php)错误处理
- 另:(Url.php)Url操作文件
- 另:(Loader.php)加载器实例化
- 另:(Input.php)数据输入
- 另:(Lang.php)语言包管理
- 另:(ORM.php)ORM基类
- 另:(Process.php)进程管理
- 另:(Session.php)session操作
- 另:(Template.php)模板解析
- 框架驱动
- D:(\config)配置解析
- D:(\controller)控制器扩展
- D:(\model)模型扩展
- D:(\db)数据库驱动
- D:(\view)模板解析
- D:(\template)模板标签库
- D:(\session)session驱动
- D:(\cache)缓存驱动
- D:(\console)控制台
- D:(\process)进程扩展
- T:(\traits)Trait目录
- D:(\exception)异常实现
- D:(\log)日志驱动
- 使用范例
- 服务器与框架的安装
- 控制器操作
- 数据模型操作
- 视图渲染控制
- MVC开发初探
- 模块开发
- 入口文件定义全局变量
- 运行模式开发
- 框架配置
- 自动生成应用
- 事件与插件注册
- 路由规则注册
- 输出控制
- 多种应用组织
- 综合应用
- tp框架整合后台auto架构快速开发
- 基础原理
- php默认全局变量
- php的魔术方法
- php命名空间
- php的自动加载
- php的composer
- php的反射
- php的trait机制
- php设计模式
- php的系统时区
- php的异常错误
- php的输出控制
- php的正则表达式
- php的闭包函数
- php的会话控制
- php的接口
- php的PDO
- php的字符串操作
- php的curl
- 框架心得
- 心:整体结构
- 心:配置详解
- 心:加载器详解
- 心:输入输出详解
- 心:url路由详解
- 心:模板详解
- 心:模型详解
- 心:日志详解
- 心:缓存详解
- 心:控制台详解
- 框架更新
- 4.20(验证类,助手函数)
- 4.27(新模型Model功能)
- 5.4(新数据库驱动)
- 7.28(自动加载)