## 了解命名空間
namespace是PHP5.3版本加入的新特性,用來解決在編寫類庫或應用程序時創建可重用的代碼如類或函數時碰到的兩類問題:
1. 用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字沖突。
2. 為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,提高源代碼的可讀性。
PHP 命名空間中的元素使用了類似文件系統的原理(同一目錄下不允許有兩個相同名稱的文件)。例如,類名可以通過三種方式引用:
1. 非限定名稱,或不包含前綴的類名稱,例如 `$a=new foo()`; 或 `foo::staticmethod()`;。如果當前命名空間是 `currentnamespace`,`foo` 將被解析為 `currentnamespace\foo`。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會被解析為foo。 **警告:如果命名空間中的函數或常量未定義,則該非限定的函數名稱或常量名稱會被解析為全局函數名稱或常量名稱。詳情參見 使用命名空間:后備全局函數名稱/常量名稱。**
2. 限定名稱,或包含前綴的名稱,例如 `$a = new subnamespace\foo();` 或 `subnamespace\foo::staticmethod();`。如果當前的命名空間是 `currentnamespace`,則 foo 會被解析為 `currentnamespace\subnamespace\foo`。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會被解析為`subnamespace\foo`。
3. 完全限定名稱,或包含了全局前綴操作符的名稱,例如, `$a = new \currentnamespace\foo()`; 或 `\currentnamespace\foo::staticmethod();`。在這種情況下,foo 總是被解析為代碼中的文字名`(literal name)currentnamespace\foo`。
另外注意訪問任意全局類、函數或常量,都可以使用完全限定名稱,例如 `\strlen()` 或 `\Exception` 或 `\INI_ALL`。**如果代碼是在命名空間內,那基本上是必須以完全限定名稱來聲明使用**
```php
<?php
use My\Full\Classname as Another, My\Full\NSname; //別名導入,如果不用as就是最后一級的名稱
$obj = new Another; // 實例化一個 My\Full\Classname 對象(非限定名稱)
$obj = new \Another; // 實例化一個Another對象(完全限定名稱)
$obj = new Another\thing; // 實例化一個My\Full\Classname\thing對象(限定名稱,限定最后一級)
$obj = new \Another\thing; // 實例化一個Another\thing對象(完全限定名稱)
$a = \strlen('hi'); // 調用全局函數strlen
$b = \INI_ALL; // 訪問全局常量 INI_ALL
$c = new \Exception('error'); // 實例化全局類 Exception
?>
```
## PSR-0 與 PSR-4
PSR是由PHP Framework Interoperability Group(PHP通用性框架小組)發布的一系列標準/規范,目前官方發布文件版本
PSR-0(已棄用)
PSR-1 基本代碼規范
PSR-2 代碼風格規范
PSR-2 補充文檔
PSR-3 日志接口規范
PSR-4 自動載入
PSR-5和PSR-6投票還未通過
PSR-0就是其中的自動加載標準,其后的PSR-4稱為改進的自動加載的標準,是PSR-0的補充。所以,PSR-0雖然被棄用了,但是我們還是了解一下。
1. 命名空間必須與絕對路徑一致
1. 類名首字母必須大寫,并且與文件名相同
1. 除去入口文件外,其他“.php”必須只有一個類
1. php類文件必須自動載入,不采用include等
1. 單一入口
>[info] 命名空間還為PHP-FIG制定的PSR-4自動加載標準奠定了堅實的基礎,現在的框架基本上都是基于`psr-4`來加載(內部spl_autoload_register加載時,通過命名空間知道其具體的絕對路徑), 其核心就是
> 作為“命名空間前綴”,其必須與至少一個“文件基目錄”相對應;
> 所謂的文件基目錄:
>
> > 1. 文件根目錄
> > 2. omposer.json里面定義的psr-4,比如psr-4定義了/app, 那/app/service/class1.php 其命名空間就是app/service; `new app/service/class1` 都可以自動加載
> > 3. 框架中提前定義好的,比如tp5中的extend目錄, extend/libs/log.php 其命名空間可以直接是libs,因為其在自動加載時會自動加上extend目錄,來加載
參考:
[PHP-FIG/PSR-4-autoloader-cn.md](https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md)
## 一個簡單的PSR-0的框架模型

`\index.php`
```php
<?php
define('BASEURL' , __DIR__);
require_once(BASEURL . '/Config/Loader.php');
spl_autoload_register('\\Config\\Loader::autoload');
Controller\Home\index::tbb();
```
`Config\Loader.php`
```php
<?php
namespace Config;
class Loader{
public function test(){
echo __DIR__ , "\n"; // 通過Config\Loader::test()調用;由此可見已經和路徑一致,更便于代碼的閱讀
}
//需要被spl_autoload_register注冊的autoloader函數必須是static;
static function autoload($class){
//echo $class; // 連命名空間也一起打印出來的,所以根據這個命名空間的特性再加上PSR-0規范的基礎上可以做類自動加載是很方便的;
$class = BASEURL . '/' . str_replace('\\' , '/' , $class) . '.php'; //Linux系統的目錄都是以/來分割的,同時windows系統雖然以\來分割目錄,但也識別/來分割,可以做一個替換;
require_once($class);
}
}
```
`Controller\Home\index`
```php
<?php
namespace Controller\Home;
class index{
public function tbb(){
echo 'i am tbb,hahahah~';
}
}
```
- 現代化PHP特性
- php7常用特性整理
- 反射機制Reflection
- 依賴注入與服務容器
- 抽象類與接口
- 類多繼承的替代方案Traits
- 類的延遲綁定(后期綁定)
- 生成器語法
- 匿名函數和閉包
- 匿名類
- 理解php的output buffer
- 斷言ASSERT
- 魔術方法小結
- Zend Opcache字節碼緩存
- 內置的http服務器
- SPL標準庫
- 【SPL標準庫專題(1)】SPL簡介
- 【SPL標準庫專題(2)】Iterator
- 【SPL標準庫專題(3)】Classes
- 【SPL標準庫專題(4)】Exceptions
- 【SPL標準庫專題(5)】Datastructures:SplDoublyLinkedList
- 【SPL標準庫專題(6)】Datastructures:SplStack & SplQueue
- 【SPL標準庫專題(7)】Datastructures:SplPriorityQueue
- 【SPL標準庫專題(8)】Datastructures:SplHeap & SplMaxHeap & SplMinHeap
- 【SPL標準庫專題(9)】Datastructures:SplFixedArray
- 【SPL標準庫專題(10)】Datastructures:SplObjectStorage
- PHPcomposer使用手札[ing]
- PHP中的多態
- 通過命名空間實現自動加載的框架雛形
- 日期與金額
- PHPstorm使用攻略
- 筆記本