PHP命名空間與自動加載簡述

圖片來自www.ngchina.com.cn網

命名空間(PHP 5 >= 5.3.0, PHP 7)

什麼是命名空間?從廣義上來講,命名空間是一種封裝事物的方法。在不少地方均可以見到這種抽象概念。例如,在操做系統中目錄用來將相關文件分組,對於目錄中的文件來講,它就扮演了命名空間的角色。具體舉個例子,文件 foo.txt 能夠同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 文件。另外,在目錄 /home/greg 外訪問 foo.txt 文件時,咱們必須將目錄名以及目錄分隔符放在文件名以前獲得 /home/greg/foo.txt。這個原理應用到程序設計領域就是命名空間的概念。php

在PHP中,命名空間用來解決在編寫類庫或應用程序時建立可重用的代碼如類或函數時碰到的兩類問題:composer

  1. 用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。
  2. 爲很長的標識符名稱(一般是爲了緩解第一類問題而定義的)建立一個別名(或簡短)的名稱,提升源代碼的可讀性。

PHP 命名空間提供了一種將相關的類、函數和常量組合到一塊兒的途徑。函數

舉栗子:ui

file.php 文件
<?php
// 使用namespace關鍵字定義命名空間,
// 且以前不能有東西
namespace Test;  
const IN = 'oooo';
function tete() {
    return __METHOD__;
}
class lala {
    function init() {
        return __METHOD__;
    }
}
autoload.php 文件
<?php
include 'file.php';
// 函數和常量是不支持use導入規則的,只有類能支持導入規則。
// 若是隻是使用use Test就會報錯 The use statement with non-compound name 'Test' has no effect in..
use Test\lala;   // 也能夠use Test\lala as lululu;
echo Test\IN."\n";
$te = new lala(); // new lululu(); // 也可使用這樣的方式來避免兩個相同的類名稱
複製代碼

總結:spa

  • 雖然任意合法的PHP代碼均可以包含在命名空間中,但只有如下類型的代碼受命名空間的影響,它們是:類(包括抽象類和traits)、接口、函數和常量。
  • 命名空間經過關鍵字namespace 來聲明。若是一個文件中包含命名空間,它必須在其它全部代碼以前聲明命名空間,除了一個之外:declare關鍵字。
  • 與目錄和文件的關係很象,PHP 命名空間也容許指定層次化的命名空間的名稱。如「namespace MyProject\Sub\Level;」
  • 也能夠在同一個文件中定義多個命名空間,可是要使用大括號的形式。例如:
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
複製代碼

以上這些是簡單的概述,詳情請移步php官網操作系統

自動加載

在編寫面向對象(OOP) 程序時,不少開發者爲每一個類新建一個 PHP 文件。 這會帶來一個煩惱:每一個腳本的開頭,都須要包含(include)一個長長的列表(每一個類都有個文件)。例如:.net

<?php

include "test1.php";
include "test2.php";
include "test3.php";
......
複製代碼

那如何避免這種狀況呢? 在 PHP 5 中,已經再也不須要這樣了。 spl_autoload_register() 函數能夠註冊任意數量的自動加載器,當使用還沒有被定義的類(class)和接口(interface)時自動去加載。經過註冊自動加載器,腳本引擎在 PHP 出錯失敗前有了最後一個機會加載所需的類。舉一個栗子:設計

lala.php 文件
<?php
class lala {
    function init() {
        return __METHOD__;
    }
}

autoload.php 文件
<?php
spl_autoload_register(function ($class_name){
    // 在這裏引入將要加載的類文件
    // 可是有一點,加載的類文件的文件名稱必須是和類名稱同樣
    require_once $class_name.'.php'; 
});
$tt = new lala();
$tt->init();
複製代碼

如今隨便一個很小的項目都須要幾十個甚至幾百個類,固然了不一樣功能的類還須要區分在不一樣的文件夾中,這樣加載就有點麻煩了。 在這裏咱們引入PSR-4自動加載規範。結合上面咱們所講到的命名空間,在規範內就能夠輕鬆解決咱們心裏的擔心。code

.目錄結構
├── App
│   └── MyClass.php
└── test.php
MyClass.php文件
<?php 
namespace App;
class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}

test.php文件
<?php
spl_autoload_register(function($class_name) {
	require_once str_replace('\\','/',$class_name).'.php';
});
use App\MyClass as MC;
$obj = new MC();
echo $obj->WhoAmI()."\n";  // App\MyClass::WhoAmI
複製代碼

這只是一個簡單的例子,想要了解實際項目中的自動加載的概念,能夠移步composer。固然了首先要知道PSR-4的相關規範......cdn

時2018年4月24日寫

相關文章
相關標籤/搜索