[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(自動加載)