有一個專案 school 和兩個函式庫 lib_a、lib_b,好死不死這兩個函式庫中的 class 名稱是一樣的,都叫做 Student,但是功能不太一樣,兩個都要用到,別人寫的函式庫改不了阿,那只好硬著頭皮希望他能跑了
school 專案的目錄結構
school
├─lib_a
│ └─Student.php
├─lib_b
│ └─Student.php
└─index.php
lib_a/Student.php 和 lib_b/Student.php 的程式
class Student {
public function __construct(
public int $id,
public string $name,
) {
}
// ...
}
index.php 的程式
require __DIR__ . '/lib_a/Student.php';
require __DIR__ . '/lib_b/Student.php';
$student = new Student(1, 'John');
echo 'success';
執行看看
$ php "d:\_code\php\school\index.php"
Fatal error: Cannot declare class Student, because the name is already in use in D:\_code\php\school\lib_b\Student.php on line 3
Call Stack:
0.0003 366088 1. {main}() D:\_code\php\school\index.php:0
0.0101 366672 2. require('D:\_code\php\school\lib_b\Student.php') D:\_code\php\school\index.php:4
果不其然炸掉了,有兩個 Student 怎麼可能知道要 new 哪一個,不過是在更前面 require 載入檔案時就掛了,並且錯誤訊息說:「這個 Student 名稱被用過了,你換一個吧」
現在有了 namespace,各家的函式庫可以指定自己的 class 或 function 是屬於哪裡的,用法也很簡單,在檔案的開頭設定 namespace 就行了,使用時在 class 前多加它的 namespace,可以想像成檔案的目錄,通常也會跟檔案目錄有對應
school 專案的目錄結構
school
├─lib_a
│ └─Student.php
├─lib_b
│ └─Student.php
└─index.php
lib_a/Student.php 的程式
namespace lib_a;
class Student {
public function __construct(
public int $id,
public string $name,
) {
}
// ...
}
lib_b/Student.php 的程式
namespace lib_b;
class Student {
public function __construct(
public int $id,
public string $name,
) {
}
// ...
}
index.php 的程式
require __DIR__ . '/lib_a/Student.php';
require __DIR__ . '/lib_b/Student.php';
$student1 = new \lib_a\Student(1, 'John');
$student2 = new \lib_b\Student(1, 'Adam');
echo 'success';
再執行看看
$ php "d:\_code\php\school\index.php"
success
這次就沒問題了,namespace 真是幫了個大忙,以後再也不用擔心函式庫名稱衝突的問題了
use 有三種用法,所以先再新增一個 lib_c,還有在 index 載入 lib_c
school 專案的目錄結構
school
├─lib_a
│ └─Student.php
├─lib_b
│ └─Student.php
├─lib_c
│ └─members
│ └─Student.php
└─index.php
lib_c/members/Student.php 的程式
namespace lib_c\members;
class Student {
public function __construct(
public int $id,
public string $name,
) {
}
// ...
}
index.php 的程式
require __DIR__ . '/lib_a/Student.php';
require __DIR__ . '/lib_b/Student.php';
require __DIR__ . '/lib_c/members/Student.php';
use lib_a\Student;
use lib_b\Student as BStudent;
use lib_c\members;
$student1 = new Student(1, 'John');
$student2 = new BStudent(1, 'Adam');
$student3 = new members\Student(1, 'Yuna');
echo 'success';
再執行看看
$ php "d:\_code\php\school\index.php"
success
use 是用建立別名的,讓程式中不會塞進一堆 namespace
namespace 和 use 很簡單吧 (比起前面那些 SSH 來 SSH 去的東西),相信你很快也能上手