使用場(chǎng)景
大部分情況都需要多個(gè)文件才可以業(yè)務(wù),這就會(huì)出現(xiàn)類名沖突的情況發(fā)生蝶俱,命名空間可以解決這類問(wèn)題人实昨。
在操作系統(tǒng)中目錄用來(lái)將文件管理,它就扮演了命名空間的角色窗看。例如文件foo.txt 可以同時(shí)在目錄/home/greg 和 /home/other 中存在茸歧,但在同一個(gè)目錄中不能存在兩個(gè) foo.txt 文件。另外显沈,在目錄 /home/greg 外訪問(wèn) foo.txt 文件時(shí)软瞎,我們必須將目錄名以及目錄分隔符放在文件名之前得到/home/greg/foo.txt逢唤。這 個(gè)原理應(yīng)用到程序設(shè)計(jì)領(lǐng)域就是命名空間的概念。
基本使用
默認(rèn)情況下常量涤浇、類和函數(shù)名都放在全局空間下鳖藕。命名空間通過(guò)namespace 來(lái)聲明。
namespace 必須定義在文件頭部只锭,并在 declare(strict_types=1) 語(yǔ)句下面吊奢。
helper.php
function sum()
{
return 'helper sum';
}
test.php
namespace PFinalClub;
include 'helper.php';
function sum()
{
return 'pfinal sum';
}
# 使用當(dāng)前命名空間中的sum
echo sum();
# 使用 helper.php 中的sum
echo \sum();
- 不指定命名空間時(shí)將使用當(dāng)前命名空間
- 如果命名空間中的函數(shù)或常量未定義,將會(huì)使用全局命名空間
子命名空間
PHP 命名空間也允許指定層次化的命名空間的名稱纹烹,如 App\Controller 形式页滚,一般情況下我們將層次與目錄結(jié)構(gòu)匹配。
namespace App\Controller;
class Bootstrap
{
public function make()
{
return __METHOD__;
}
}
引入方式
非限定名稱
調(diào)用類時(shí)沒有指定命名空間時(shí)铺呵,將使用當(dāng)前命名空間裹驰。
下面在使用 User 時(shí)沒有指定命名空間將使用當(dāng)前命名空間。
namespace App;
class User
{
public function make()
{
return __METHOD__;
}
}
$user = new User;
echo $user->make();
限定名稱
限定名稱類似于文件系統(tǒng)中的相對(duì)路徑 片挂。
Order.php
namespace App\Controller;
class Order
{
public static function make()
{
return __METHOD__;
}
}
Test.php
namespace App;
include 'Order.php';
class User
{
public static function make()
{
return __METHOD__;
}
}
echo Controller\Order::make();
使用限定名稱調(diào)用 Order 類幻林,系統(tǒng)會(huì)使用當(dāng)前命名空間加上 Controller 做為 Order 類的命名空間。
完全限定名稱
類似于文件系統(tǒng)中的絕對(duì)路徑音念,以下面的代碼為例沪饺,調(diào)用Order類時(shí)可以使用以下的完全限定方式。
echo \App\Controller\Order::make();
常量
常量 NAMESPACE 的值是包含當(dāng)前命名空間名稱的字符串闷愤。
<?php
namespace App;
function factory($class)
{
return __NAMESPACE__ . '\\' . $class;
}
class User
{
public static function make()
{
return __METHOD__;
}
}
class Order
{
public static function make()
{
return __METHOD__;
}
}
echo factory('Order')::make();
使用 namespace 關(guān)鍵字
<?php
namespace App;
class Order
{
public static function make()
{
return __METHOD__;
}
}
echo namespace\Order::make();
別名引入
通過(guò)操作符 use 來(lái)為類或命名空間使用別名整葡。
基本使用
本實(shí)例使用的示例目錄結(jié)構(gòu)如下:
App
--Controller
-- Comment.php
-- User.php
boot.php
boot.php
namespace Houdunren;
use App\Controller\User;
include 'App/Controller/User.php';
echo User::make();
如果使用 use App\Controller,在引入 User 類時(shí)方法如下
Controller\User::make()
別名
在引入多個(gè)同名類時(shí)會(huì)有沖突情況發(fā)生讥脐,可以通過(guò)起別名的方式處理
namespace pfinal;
use App\Controller\User as Member;
include 'App/Controller/User.php';
echo Member::make();
多個(gè)引入
可以使用多行 use 或用逗號(hào)分隔多個(gè)類(空間)形式處理多個(gè)導(dǎo)入的情況
namespace pfinal;
use App\Controller\User as Member;
use App\Controller\Comment;
include 'App/Controller/User.php';
include 'App/Controller/Comment.php';
echo Member::make();
使用逗號(hào)分隔
<?php
...
use App\Controller\User as Member, App\Controller\Comment;
...
自動(dòng)加載
注冊(cè)加載
以往的 __autoload 自動(dòng)加載函數(shù)已經(jīng)在 php7.2 廢棄使用遭居,所以使用 spl_autoload_register 函數(shù)完成自動(dòng)加載處理。
spl_autoload_register(function (string $class) {
$file = str_replace('\\', '/', $class) . '.php';
if (!is_file($file)) {
throw new \Exception("file don't exists");
}
require $file;
});
使用類方法實(shí)現(xiàn)
class Bootstrap
{
public function autoload($class)
{
$file = str_replace('\\', '/', $class) . '.php';
if (!is_file($file)) {
throw new \Exception("file don't exists");
}
require $file;
}
}
spl_autoload_register([new Bootstrap, 'autoload']);
composer
使用composer 是PFinal社區(qū)建議使用的方式旬渠,下面簡(jiǎn)略介紹使用方法俱萍。
項(xiàng)目初始
$ composer init
直行上面命令并一直回車下去
修改配置文件
個(gè)性 composer.json 配置文件,其中 autoload 配置項(xiàng)是自動(dòng)加載設(shè)置告丢。
- files 是自動(dòng)加載文件列表枪蘑,適合于加載函數(shù)
- psr-4 自動(dòng)加載命名空間與目錄對(duì)應(yīng)關(guān)系
{
"name": "pf/php",
"authors": [
{
"name": "pf.com",
"email": "lampxiezi@163.com"
}
],
"autoload": {
"files": [
"App/helper.php"
],
"psr-4": {
"App\\": "App"
}
},
"require": {}
}
安裝與更新
修改配置文件后執(zhí)行 composer install 生成 vendor,如果修改過(guò)配置文件需要執(zhí)行 composer update岖免。
配置
在項(xiàng)目中使用以下代碼即可完成自動(dòng)加載岳颇。
include 'vendor/autoload.php';