Namespaces ในภาษา PHP

Namespace คืออะไร

ในการเขียนโปรแกรม namespaces คือสัญลักษณ์ที่ใช้ในการจัดเก็บกลุ่มของคลาสและเมธอดให้เป็นกลุ่มเดียวกัน โดย namespaces นั้นจะมีการอ้างถึงโดยชื่อของมัน ในภาษา PHP คุณสามารถสร้าง namespaces สำหรับเก็บคลาสและเมธอดได้ แนวคิดของ namespaces ในการเขียนโปรแกรมนั้นเหมือนกับไฟล์ระบบในคอมพิวเตอร์ namespaces จะเป็นเหมือนโฟล์เดอร์สำหรับแยกข้อมูลออกเป็นกลุ่มหรือคนละประเภท และข้อมูลในโฟล์เดอร์นั้นเปรียบได้กับออบเจ็คใน namespaces

File system concept in namespace PHP

จากรูปด้านบนเป็นโครงสร้างต้นไม้ของไฟล์ระบบในคอมพิวเตอร์ที่เป็นแนวคิดเดียวกับ 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 ให้สั้นลง


บทความเกี่ยวกับ Namespaces

Namespaces ในภาษา C#

ในภาษา C# เนมสเปซ (namespace) นั้นเป็นเซตของเมธอดและคลาส ที่ใช้ในการจัดการสิ่งเหล่านี้ให้เป็นกลุ่ม หรือเป็นการรวบรวมของออบเจ็ค มันเป็นแนวคิดแบบนามธรรมที่ใช้ในก...