Namespaces ในภาษา PHP
Namespace คืออะไร
ในการเขียนโปรแกรม namespaces คือสัญลักษณ์ที่ใช้ในการจัดเก็บกลุ่มของคลาสและเมธอดให้เป็นกลุ่มเดียวกัน โดย namespaces นั้นจะมีการอ้างถึงโดยชื่อของมัน ในภาษา PHP คุณสามารถสร้าง namespaces สำหรับเก็บคลาสและเมธอดได้ แนวคิดของ namespaces ในการเขียนโปรแกรมนั้นเหมือนกับไฟล์ระบบในคอมพิวเตอร์ namespaces จะเป็นเหมือนโฟล์เดอร์สำหรับแยกข้อมูลออกเป็นกลุ่มหรือคนละประเภท และข้อมูลในโฟล์เดอร์นั้นเปรียบได้กับออบเจ็คใน namespaces
จากรูปด้านบนเป็นโครงสร้างต้นไม้ของไฟล์ระบบในคอมพิวเตอร์ที่เป็นแนวคิดเดียวกับ namespace โดยมี root directory เป็น marcuscode ซึ่งเปรียบได้เหมือน top level namespace
Namespaces ยังช่วยการในแก้ไขปัญหาการขัดแย้งของชื่อคลาสที่เหมือนกันในโปรแกรม ยกตัวอย่างเช่น บริษัทสองบริษัทคือ A และ B ต้องการนำโค้ดของพวกเขามารวมเข้าด้วยกัน เพื่อสร้างเป็นแอพพลิเคชันใหม่ โดยปกติในการเขียนโปรแกรมเราไม่สามารถสร้างคลาสที่มีชื่อเหมือนกันได้ ทั้งบริษัท A และบริษัท B ต่างก็มีคลาสที่ชื่อว่า ConnectDatabase
ดังนั้น namespace สามารถช่วยให้เราสามารถมีชื่อคลาสเหมือนกันได้ภายใน namespace ที่แตกต่างกัน นี่เป็นรูปแบบการสร้าง namespaces ในภาษา PHP
namespace NamespaceName;
// namespace members
ในตัวอย่าง เป็นรูปแบบการประกาศ namespace ในภาษา PHP เราใช้คำสั่ง namespace
และตามด้วยชื่อ NamespaceName
คำสั่งทั้งหมดหลังจากคำสั่งของการประกาศ namespace นั้นจะเป็นสมาชิกของ namespace และคำสั่งในการประกาศ namespace ต้องอยู่ก่อนบรรทัดอื่นของโค้ดเสมอ
namespace NamespaceName {
// namespace members
}
นอกจากนี้ในภาษา PHP คุณยังสามารถประกาศ namespace ในรูปแบบของ block เช่นเดียวกันคลาส เหมือนในตัวอย่างข้างบน
การสร้างและใช้งาน Namespaces
ต่อมาดูตัวอย่างการประกาศ namespace ในภาษา PHP เราจะประกาศ namespace สำหรับเก็บคลาสและใช้งาน namespace ดังกล่าว
<?php
// marcuscode_namespace.php
namespace marcuscode;
class User {
public $firstName;
function getName() {
return $this->firstName;
}
}
?>
ในตัวอย่าง เป็นการประกาศ namespace ที่มีชื่อว่า marcuscode
โดยเราแยกส่วนของ namespace นี้ในไฟล์ที่ชื่อว่า marcuscode_namespace.php
ใน namespace นั้นมีการกำหนดคลาส User
ซึ่งคลาสนี้เป็นสมาชิกของ namespace นั่นเอง ต่อไปจะเป็นการใช้งาน namespace ดังกล่าว
<?php
include_once 'namespace.php';
use marcuscode\User;
$user1 = new User();
$user1->firstName = "Mateo";
echo $user1->getName(), "\n";
?>
ในตัวอย่าง เป็นการใช้งานคลาสภายใน namespace marcuscode
เราได้ใช้ฟังก์ชัน include_once()
ในการโหลด namespace จากไฟล์ namespace.php
เข้ามายังโปรแกรมปัจจุบัน
use marcuscode\User;
นี่เป็นคำสั่งในการใช้งานคลาสภายใน namespace โดยการใช้คำสั่ง use
แล้วตามด้วยชื่อคลาสหรือออบเจ็คภายใน namespace ที่ต้องการใช้งาน ในตัวอย่างนั้นหมายถึงเป็นการใช้งานคลาส User
ภายใน namespace marcuscode
$user1 = new User();
เมื่อเราได้เรียกคำสั่งในการใช้งาน namespace แล้ว เราสามารถใช้งานคลาสนี้ได้เหมือนกับการใช้คลาสปกติ
Mateo
นี่เป็นผลลัพธ์ของโปรแกรมในการใช้ namespace ในภาษา PHP
การสร้าง sub namespace
เช่นเดียวกันกับระบบโครงสร้างไฟล์ในคอมพิวเตอร์ namespace สามารถที่จะซ้อนกันได้ สำหรับจัดกับออบเจ็คต่างๆ ซึ่งอาจจะมีหมวดหมู่ย่อยลงไปได้อีก ต่อไปเป็นตัวอย่างในการประกาศและใช้งาน sub namespace ในภาษา PHP
<?php
namespace marcuscode;
class User {
public $firstName;
function getName() {
return $this->firstName;
}
}
namespace marcuscode\Database;
class Connection {
// Connection to database
function __construct() {
echo "Connected to database\n";
}
}
namespace marcuscode\Utilities;
class String {
// String utilities class
function __construct() {
echo "String utilities class created\n";
}
}
class Time {
const TIME_ZONE = -5;
public static $city = "Manhattan";
}
?>
ในตัวอย่าง เป็นการสร้าง namespace ที่มีการซ้อนกัน โดย root ของ namespace นั้นมีชื่อว่า marcuscode
ภายใน namespace นี้จะมี namespace ย่อยลงไปอีกคือ Database
และ Utilities
เหมือนโครงสร้างของต้นไม้ เพื่อสร้างหรือใช้งาน namespace ที่มากกว่าหนึ่งชั้นนั้นเราใช้เครื่องหมาย \
backslash นี่เป็นตัวอย่างในการใช้งาน namespace ดังกล่าว
<?php
include 'namespace.php';
use marcuscode\User;
use marcuscode\Database\Connection;
use marcuscode\Utilities;
$user = new User();
$db = new Connection();
$string = new Utilities\String();
// access constant and static variable in time class
echo "City = " ,Utilities\Time::$city , "\n";
echo "Time zone = ", Utilities\Time::TIME_ZONE, "\n";
?>
เพื่อใช้งาน namespace เราต้องทำการนำเข้า namespace ที่ต้องการใช้เข้ามาในโปรแกรม ซึ่งมีสองแบบคือ การเข้าถึงโดยตรง
use marcuscode\User;
use marcuscode\Database\Connection;
ในสองคำสั่งนี้เป็นการเข้าถึงการใช้งาน namespace โดยตรง โดยเราจะต้องเข้าไปจนถึงคลาสที่ต้องการใช้งาน ในการใช้งานคลาสเราสามารถเรียกใช้ชื่อของคลาสได้ทันที โดยที่ไม่ต้องมี parent prefix ข้างหน้า เหมือนในการสร้างคลาสของตัวแปร $user
และ $db
use marcuscode\Utilities;
...
$time = new Utilities\Time();
$string = new Utilities\String();
ในตัวอย่าง เป็นการนำเข้า namespace แบบกว้าง เราได้เรียกใช้ namespace ถึงเพียง marcuscode\Utilities
เพื่อเข้าถึงคลาสภายใน sub namespace นี้ เราจำเป็นต้องใช้ถึงผ่าน scope ที่เรียกใช้ในปัจจุบันคือ Utilities
ยกตัวอย่างเช่น เราต้องการเข้าถึงคลาส Time
เราจะอ้างถึงคลาสโดย Utilities\Time
เป็นต้น
<?php
include 'namespace.php';
use marcuscode\User;
use marcuscode\Database\Connection;
use marcuscode\Utilities;
$user = new User();
$db = new Connection();
$string = new Utilities\String();
// access constant and static variable in time class
echo "City = " ,Utilities\Time::$city , "\n";
echo "Time zone = ", Utilities\Time::TIME_ZONE, "\n";
echo "Current date = ", Utilities\Time::getCurrentDate(), "\n";
?>
ในคำสั่งเป็นการเข้าถึงค่าคงที่และตัวแปรแบบ static และเมธอดภายในคลาส Time
ที่อยุ่ภายใน namespace โดยการใช้เครื่องหมาย ::
และตามด้วยชื่อของออบเจ็คที่ต้องการเข้าถึง
Connected to database
String utilities class created
City = New York
Time zone = -5
Current date = January 22, 2017
นี่เป็นผลลัพธ์การทำงานของโปรแกรมของการสร้างและใช้งาน sub namespace ในภาษา PHP
การใช้งาน multiple-namespace ในโปรแกรม
ในการเขียนโปรแกรมนั้น โดยปกติเราไม่สามารถสร้างคลาสที่มีชื่อเดียวกันได้ภายในโปรแกรม แต่คุณสามารถสร้างคลาสที่มีชื่อเหมือนกันได้ใน namespace ที่แตกต่างกัน และเราสามารถใช้งานคลาสเหล่านั้นได้พร้อมกันในโปรแกรม ซึ่งนี่ช่วยให้นักพัฒนาสามารถนำโค้ดมารวมเข้าด้วยกันได้ ยกตัวอย่างเช่น บริษัท A ต้องการใช้คลาสจากบริษัท B แต่คลาสในบริษัท B นั้นมีชื่อตรงกันกับคลาสในบริษัท A ดังนั้นเราใช้ namespace ในการแก้ไขปัญหานี้ มาดูตัวอย่างการใช้งานในภาษา PHP
<?php
// companies_namespaces.php
namespace CompanyA;
class Person {
public $firstName;
public $lastName;
function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function GetName() {
return $this->firstName. ' ' . $this->lastName ;
}
}
namespace CompanyB;
class Person {
public $firstName;
public $lastName;
public $age;
function __construct($firstName, $lastName, $age) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->age = $age;
}
public function GetName() {
return $this->firstName . ' ' . $this->lastName
. " is $this->age year old";
}
}
?>
ในตัวอย่าง เราได้สร้างสอง namespace คือ CompanyA
และ CompanyB
ซึ่งทั้งสอง namespace นั้นต่างก็มีคลาส User
เป็นของมันเอง
<?php
include_once 'companies_namespaces.php';
$person1 = new CompanyA\Person("Mateo", "Marcus");
$person2 = new CompanyB\Person("Mateo", "Marcus", 28);
echo $person1->GetName() . "\n";
echo $person2->GetName() . "\n";
?>
ต่อมาเรานำคลาสจาก namespace ทั้งสองมาสร้างคลาส ในตัวอย่างเราเข้าถึงคลาสจาก namespace โดยตรงผ่านชื่อของ namespace และตามด้วยชื่อของคลาส โดยที่ไม่ต้องใช้คำสั่ง use ออบเจ็คทั้งสอง ดังนั้นเราสามารถสร้างออบเจ็คจากคลาส User
ที่อยู่คนละ namespace ซึ่งแต่ละคลาสนั้นเป็นคนละคลาสกันอย่างสิ้นเชิง เราเรียกใช้เมธอด GetName()
ของคลาสทั้งสอง ซึ่งคลาสใน namespace CompanyA
จะแสดงชื่อและนามสกุล และคลาสใน namespace ที่สองจะมีการแสดงอายุเพิ่มเข้ามาด้วย
Mateo Marcus
Mateo Marcus is 28 year old
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ในการเข้าถึง namespace โดยตรงในภาษา PHP
Namespace aliasing การตั้งชื่อเสมือน
Namespace aliasing คือการตั้งชื่อเสมือนให้กับ namespace ไปยังชื่อที่ง่ายและสั้นกว่า ซึ่งมันสามารถอำนวยความสะดวกในการใช้งาน ยกตัวอย่างเช่น คุณมี namespace ที่มีชื่อที่ยาวมากหรือ namespace อาจจะซ้อนกันหลายชั้น การใช้ namespace aliasing จะช่วยให้คุณสามารถใช้ namespace ออบเจ็คของมันได้สั้นลง มาดูตัวอย่างการใช้งานในภาษา PHP
<?php
// marcuscode_namespace.php
namespace marcuscode;
class Language {
public $name;
public $creator;
function __construct($name, $creator) {
$this->name = $name;
$this->creator = $creator;
}
function getInfo() {
echo "$this->name was created by $this->creator";
}
}
?>
ในตัวอย่าง เราได้สร้าง namespace marcuscode
ซึ่งประกอบไปด้วยคลาส Language
ต่อไปเราจะนำคลาสนี้ไปใช้ในโปรแกรมโดยการ namespace aliasing
<?php
include_once 'marcuscode_namespace.php';
use marcuscode\Language as lang;
$lang1 = new lang("PHP", "Rasmus Lerdorf");
$lang2 = new lang("Java", "James Gosling");
echo $lang1->getInfo(), "\n";
echo $lang2->getInfo(), "\n";
?>
ในโค้ดของโปรแกรมข้างบน เป็นการใช้งานคลาส Language สำหรับสร้างออบเจ็คของภาษาที่ประกอบไปด้วยชื่อของภาษาและชื่อผู้สร้าง และเราจำได้ใช้คำสั่งสำหรับการ namespace aliasing
use marcuscode\Language as lang;
ในคำสั่งนี้เป็นการใช้งาน namespace aliasing ในภาษา PHP เราได้ทำการเปลี่ยนจาก marcuscode\Language
เป็น lang
โดยการใช้คำสั่ง as
คุณจะเห็นว่ามันทำให้ชื่อสั้นลง และเราสามารถใช้ lang
แทน marcuscode\Language
ได้ในที่ใดๆ ของโปรแกรม
PHP was created by Rasmus Lerdorf
Java was created by James Gosling
นี่เป็นผลลัพธ์ของโปรแกรมในการเปลี่ยนชื่อ namespace และคลาสให้สั้นลงโดยการ namespace aliasing ในภาษา PHP ซึ่งนี่เพิ่มความสะดวกและรวดเร็วสำหรับ namespace และคลาสที่มีชื่อยาวและซับซ้อน
ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ namespace และวิธีการใช้งานในภาษา PHP namespace นั้นเป็นสิ่งที่มีประโยนชน์และจำเป็นในการพัฒนาโปรแกรมร่วมกัน และช่วยให้จัดเก็บคลาสและไลบรารี่ได้อย่างเป็นหมวดหมู่ และมันยังสามารถแก้ไขปัญหาที่คลาสมีชื่อเหมือนกันโดยการใช้ namespace นอกจากนี้คุณยังทราบเกี่ยวกับการ namespace aliasing ซึ่งเป็นการเปลี่ยนชื่อ namespace ให้สั้นลง