เนมสเปซคืออะไร


241

PHP Namespaces คืออะไร

โดยทั่วไปเนมสเปซคืออะไร

คำตอบของคนธรรมดาพร้อมตัวอย่างจะดีมาก

คำตอบ:


573

การกำหนดเนมสเปซใช้สำหรับฟังก์ชันและคลาสที่ขอบเขตสำหรับตัวแปร อนุญาตให้คุณใช้ฟังก์ชันหรือชื่อคลาสเดียวกันในส่วนต่าง ๆ ของโปรแกรมเดียวกันโดยไม่ทำให้เกิดการชนกันของชื่อ

ในแง่ง่ายคิด namespace เป็นนามสกุลของบุคคล หากมีสองคนชื่อ "จอห์น" คุณสามารถใช้นามสกุลของพวกเขาเพื่อบอกพวกเขาออกจากกัน

สถานการณ์

output()สมมติว่าคุณเขียนโปรแกรมประยุกต์ที่ใช้ฟังก์ชั่นการตั้งชื่อ output()ฟังก์ชั่นของคุณใช้รหัส HTML ทั้งหมดในหน้าของคุณและส่งไปยังผู้ใช้

แอปพลิเคชันของคุณจะใหญ่ขึ้นและคุณต้องการเพิ่มฟีเจอร์ใหม่ คุณเพิ่มไลบรารีที่อนุญาตให้คุณสร้างฟีด RSS ไลบรารีนี้ยังใช้ฟังก์ชันชื่อoutput()เพื่อแสดงผลฟีดสุดท้าย

เมื่อคุณโทรoutput()PHP จะรู้ได้อย่างไรว่าจะใช้output()ฟังก์ชั่นของคุณหรือฟังก์ชั่นของห้องสมุด RSS output()? มันไม่ นอกเสียจากคุณกำลังใช้เนมสเปซ

ตัวอย่าง

เราจะแก้ปัญหาการมีสองoutput()ฟังก์ชั่นได้อย่างไร ง่าย เราติดแต่ละoutput()ฟังก์ชั่นในตัวของมันเองnamespace

ที่จะมีลักษณะเช่นนี้:

namespace MyProject;

function output() {
    # Output HTML page
    echo 'HTML!';
}

namespace RSSLibrary;

function output(){
    # Output RSS feed
    echo 'RSS!';
}

ต่อมาเมื่อเราต้องการใช้ฟังก์ชั่นต่าง ๆ เราจะใช้:

\MyProject\output();
\RSSLibrary\output();

หรือเราสามารถประกาศว่าเราอยู่ในหนึ่งในเนมสเปซแล้วเราก็สามารถเรียกชื่อของเนมสเปซนั้นoutput():

namespace MyProject;

output(); # Output HTML page
\RSSLibrary\output();

ไม่มีเนมสเปซ

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


ด้วยเหตุผลบางอย่างฉันคิดว่าถ้าคุณใช้เนมสเปซในไฟล์ 1 คุณไม่จำเป็นต้องมีหรือรวมไฟล์ไว้ใน file2 การทดสอบหน่วยแสดงให้เห็นว่านี่ไม่ใช่กรณี
Aaron Bell

1
@AaronBell คุณอาจต้องการที่จะตรวจสอบautoloading
cbednarski

21

เนมสเปซช่วยให้คุณสามารถวางโค้ดจำนวนมากภายใต้ชื่อและไม่มีความขัดแย้งในการตั้งชื่อกับคลาสฟังก์ชันและค่าคงที่

อนุญาตให้โค้ดของคุณอยู่ในเนมสเปซนั้น

PHP ใช้ตัวละครที่ค่อนข้างแย้ง \เพื่อแสดงระดับเนมสเปซ ผู้คนลุกขึ้นในอ้อมแขนเพราะมันใช้เป็นตัวละครในการหลบหนี

ในการใช้เนมสเปซใน PHP ให้ใช้สิ่งนี้ที่ด้านบนของไฟล์ของคุณ

namespace my\namespace;

คุณสามารถค้นหาข้อมูลมากขึ้นในเอกสารอย่างเป็นทางการสำหรับ PHP namespaces


11

เนื่องจากง่ายต่อการเรียนรู้เกี่ยวกับคำหลัก "ใช้" โดยรู้เกี่ยวกับ "namespace" ให้ฉันอธิบาย namespace ก่อนโดยดูที่โครงการ Laravel ขั้นพื้นฐาน

มีคลาสคอนโทรลเลอร์ที่มีชื่อ: Controller.phpซึ่งอยู่ในพา ธ : app / Http / Controllersจากไดเรกทอรีรากของโครงการนอกจากนี้ยังมีคลาสคอนโทรลเลอร์อีกชื่อ: Controller.phpแต่อันนี้อยู่ในพา ธ : ผู้ขาย / laravel / framework / src / Illuminate / Routingจากไดเรกทอรีรากของโครงการ

คุณไม่จำเป็นต้องดูซอร์สโค้ด แต่ถ้าคุณยังใหม่กับ php เพราะมันอาจทำให้คุณสับสนได้ขอให้ฉันอธิบายส่วนที่เราสนใจและจะช่วยให้เราเข้าใจ "namespace" และ "ใช้ ”

ดังนั้นเป็นเรื่องของความเป็นจริงระดับควบคุมครั้งแรกของเรา: app / HTTP / ควบคุม / Controller.phpจำเป็นต้องใช้ตัวควบคุมชั้นสองผู้ขาย / Laravel / กรอบ / src / สว่าง / สายงานการผลิต / Controller.php จริง ๆ แล้วมันต้องการขยายคลาสนี้เพื่อให้สามารถเข้าถึงเนื้อหาสำหรับการจัดการฟังก์ชันการกำหนดเส้นทางที่สำคัญบางอย่าง

แล้วคลาสจะขยายคลาสอื่นที่มีชื่อเดียวกันได้อย่างไร? class Controller extends Controller? สิ่งนี้จะไม่ทำงาน เว้นแต่จะมีวิธีแยกแยะความแตกต่างระหว่างสองคลาสนี้และนั่นคือที่namespaceมาที่มีประโยชน์และuseคำหลักช่วยในการทำภารกิจให้เสร็จสมบูรณ์โดยอนุญาตให้ใช้งานได้ (คลาสวิธีการอินเทอร์เฟซและค่าคงที่) ที่มีชื่อเดียวกันอยู่ในขอบเขตเดียวกัน

ตอนนี้มันทำในรหัสได้อย่างไร ง่ายมาก! ถ้าเราดูที่ซอร์สโค้ดของ app / Http / Controllers / Controller.phpเราสามารถดูได้ที่ด้านบนสุดของเนมสเปซของคลาสที่ประกาศเป็น:namespace App\Http\Controllersดังนั้นนี่คือวิธีที่คุณให้เนมสเปซกับคลาสของคุณเพื่อให้สามารถอ้างอิงโดยคลาสอื่นได้ทันที สิ่งนี้มีลักษณะเหมือนกับเส้นทางไปยังคลาสนี้จากไดเรกทอรีรูทของโครงการที่มีความแตกต่างกันเล็กน้อยและนั่นคือการใช้“\” แทน“/(เหมือนกับพรอมต์คำสั่งใน windows)แต่มีความแตกต่างอื่นและนั่นคือแอปที่มีทุน 'A' ในเนมสเปซเมื่อเทียบกับ 'แอป' กับตัวพิมพ์เล็ก 'a' ในพา ธ โปรดทราบว่าเนมสเปซจะคำนึงถึงขนาดตัวพิมพ์

ดังนั้นเนมสเปซจึงเป็นแนวคิดที่แยกต่างหากจากพา ธ มันสามารถติดตามโครงสร้างพา ธ ถ้ามันช่วยได้ แต่ไม่จำเป็นต้องเป็นพา ธ ที่แน่นอนไปยังคลาสเมธอดอินเตอร์เฟสหรือค่าคงที่ตัวอย่างเช่นลองดูที่: seller / laravel / framework /src/Illuminate/Routing/Controller.phpรหัสแหล่งที่มา

เราเห็นที่ด้านบนของคลาส namespace ถูกประกาศเป็น: Illuminate\Routing

ตอนนี้ลองมาดู“useคำสำคัญ“” เราใช้useคำสำคัญ“” เพื่อให้ชั้นเรียนของเราตระหนักถึงคลาสหรือฟังก์ชันเฉพาะที่เราต้องการใช้ในชั้นเรียนของเรา

ดังนั้นเราจึงไม่ได้นำเข้าหรือรวมถึงสิ่งใดก็ตามที่เราเพียงแค่ให้ชั้นเรียนของเรารู้ว่าเราจะใช้คลาสหรือวิธีการที่เฉพาะเจาะจงโดยอ้างอิงพวกเขาโดยเนมสเปซของพวกเราลองมาดูที่ซอร์สโค้ดของแอปคุณสามารถดูได้จากบรรทัด:“ use Illuminate\Routing\Controller as BaseController”, useคำสำคัญ“” ตามด้วยnamespace สำหรับคลาสเป้าหมาย (โปรดทราบว่า Illuminate \ Routing \ Controller.php และ Illuminate \ Routing \ Controller 'โดยไม่มีนามสกุล. php')

เราสามารถใช้asคีย์เวิร์ด“” พร้อมกับuseคีย์เวิร์ด“” เพื่อให้คลาสเมธอดอินเทอร์เฟซหรือค่าคงที่ซึ่งอนุญาตให้ แอพ / Http / Controllers / Controller.phpขยายIlluminate \ Routing \ Controller.phpเป็น BaseController ใน บรรทัด:“ class Controller extends BaseController


9

มีเทคนิคต่าง ๆ เช่น namespaces ในภาษาการเขียนโปรแกรมอื่น (เช่นแพ็คเกจใน Java) พวกเขาเคยมีคลาส mutliple ที่มีชื่อเดียวกันกับโครงการ

จากเอกสาร php ( http://www.php.net/manual/en/language.namespaces.rationale.php ):

เนมสเปซคืออะไร ในเนมสเปซที่มีคำจำกัดความกว้างที่สุดเป็นวิธีการห่อหุ้มไอเท็ม สิ่งนี้ถือเป็นแนวคิดที่เป็นนามธรรมในหลาย ๆ ที่ ตัวอย่างเช่นในไดเรกทอรีระบบปฏิบัติการใด ๆ ที่ทำหน้าที่จัดกลุ่มไฟล์ที่เกี่ยวข้องและทำหน้าที่เป็นเนมสเปซสำหรับไฟล์ที่อยู่ภายใน ตัวอย่างที่เป็นรูปธรรมไฟล์ foo.txt สามารถมีอยู่ในทั้งไดเร็กทอรี / home / greg และใน / home / other แต่ foo.txt สองสำเนาไม่สามารถอยู่ร่วมในไดเรกทอรีเดียวกันได้ นอกจากนี้ในการเข้าถึงไฟล์ foo.txt นอกไดเรกทอรี / home / greg เราจะต้องเพิ่มชื่อไดเรกทอรีให้กับชื่อไฟล์โดยใช้ตัวคั่นไดเรกทอรีเพื่อรับ /home/greg/foo.txt หลักการเดียวกันนี้รวมถึง namespaces ในโลกการเขียนโปรแกรม


1
การเปรียบเทียบกับ Java เป็นความคิดที่ไม่ดี Java มีแพ็กเกจและมีคลาสที่มองเห็นแพ็กเกจ ทัศนวิสัยของสมาชิกที่ได้รับความคุ้มครองนั้นขึ้นอยู่กับแพ็คเกจที่เข้าถึงได้
Artefacto

1
ไม่เท่ากับแพ็คเกจ แต่ใช้แนวคิดเดียวกัน
2ndkauboy

เมื่อคำถามถามว่าเนมสเปซเป็นอะไรโดยทั่วไปคำตอบก็สมเหตุสมผล
kiamlaluno

@kiam พวกเขาแบ่งปันความคิดเดียว - ไม่ใช่ชื่อคลาสที่ขัดแย้งกัน พวกเขาไม่แบ่งปันแนวคิดของการมองเห็น
Artefacto

@Artefacto: Kau-Boy ไม่ได้พูดว่า namespaces ในทั้งสองภาษาเหมือนกัน
kiamlaluno

4

เหมือนไดเรกทอรีและไฟล์ , namespace ใน PHP ให้บริการไปยังกลุ่มการเรียน , การทำงาน , การเชื่อมต่อและค่าคงที่

ตัวอย่าง:

Filesystem      |   PHP Namespace
----------------|------------------
/Dir/File.txt   |  \Namespace\Class

มันมีวิธีการห่อรายการจากพื้นที่ส่วนกลางและอนุญาตให้ใช้ชื่อรายการธรรมดาโดยไม่ทำให้เกิดการชนกันของชื่อในโปรแกรม สนับสนุนใน PHP 5.3.0, PHP 7

แต่มีข้อ จำกัด บางอย่างในการเปรียบเทียบระหว่าง PHP namespace และระบบไฟล์ที่ใช้ Unix:

                          | Filesystem            |        PHP Namespace
--------------------------|-----------------------|-------------------------
Cas sensitive             |       No              |        Yes                
--------------------------|-----------------------|-------------------------
Name with plain number    |       Yes             |        No
--------------------------|-----------------------|-------------------------
Path level                |       Yes             |        Yes   
--------------------------|-----------------------|-------------------------
Plain metacharacters name |       Yes             |        No        

หลักการขยายไปถึงเนมสเปซในการเขียนโปรแกรมคำ


3

Namespace ทำงานเหมือนไดเรกทอรี คุณรู้วิธีที่คุณสามารถวางไฟล์ในไดเรกทอรีที่มีชื่อเดียวกันกับไฟล์ในไดเรกทอรีหลัก (หรืออื่น ๆ )? เนมสเปซช่วยให้คุณทำเช่นนั้นภายในแอปพลิเคชันสำหรับตัวแปรฟังก์ชันและคลาส

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


2

เนมสเปซโดยทั่วไปช่วยให้คุณใส่รหัสลงในคอนเทนเนอร์ สิ่งนี้จะป้องกันปัญหาเกี่ยวกับสองฟังก์ชัน (รวมถึงคลาสและตัวแปร) ที่ใช้ชื่อเดียวกัน

สิ่งเหล่านี้มีประโยชน์เมื่อทำงานเมื่อแอปพลิเคชันขนาดใหญ่ขึ้นเพื่อป้องกันปัญหาเกี่ยวกับรหัสที่ใช้ชื่อเดียวกันร่วมกัน

ตัวอย่างเช่นสมมติว่าเราต้องการฟังก์ชั่นสองอย่างที่เรียกว่า "TheMessage" ทั้งสองนี้จะพิมพ์ (echo) ข้อความต่างกัน โดยปกติสิ่งนี้จะทำให้เกิดข้อผิดพลาดทางไวยากรณ์เนื่องจากคุณไม่สามารถมีสองฟังก์ชันที่ใช้ชื่อเดียวกันได้

ในการแก้ไขปัญหานี้คุณสามารถใส่ฟังก์ชั่นเหล่านี้ในเนมสเปซที่แยกต่างหาก สิ่งนี้จะทำให้คุณสามารถใช้ทั้งสองฟังก์ชั่นได้โดยไม่มีข้อผิดพลาด


2

Namespace เปรียบเสมือนการบรรจุหลาย ๆ อย่างไว้ในหีบห่อเดียว ลองนึกภาพเนมสเปซเป็นลิ้นชักซึ่งคุณสามารถใส่ของได้ทุกอย่างไม่ว่าจะเป็นดินสอไม้บรรทัดไม้บรรทัดกระดาษและอื่น ๆ เพื่อหลีกเลี่ยงการใช้รายการของกันและกันคุณตัดสินใจที่จะติดป้ายลิ้นชักเพื่อให้ชัดเจนว่าเป็นของใคร


0

เนมสเปซใช้เพื่อใส่รหัสกลุ่มเพื่อให้สามารถใช้ในที่ต่าง ๆ ได้โดยไม่ต้องขัดแย้งกับชื่อ คิดว่านี่เป็น jQuery ไม่มีวิธีการขัดแย้งและคุณจะเข้าใจได้ดีขึ้น


คุณหมายถึงอะไรโดย "jQuery no method method" มันเกี่ยวข้องกับ PHP อย่างไร?
Nico Haase

0

เนมสเปซเป็นระบบง่าย ๆ ในการควบคุมชื่อในโปรแกรม
ช่วยให้มั่นใจได้ว่าชื่อจะไม่ซ้ำกันและจะไม่นำไปสู่ความขัดแย้งใด ๆ


คุณกำลังพูดถึงชื่อประเภทใด
Nico Haase

0

คุณสามารถใช้เนมสเปซเพื่อหลีกเลี่ยงการชนกันของชื่อระหว่างรหัสที่คุณสร้างและคลาส PHP / ฟังก์ชั่น / ค่าคงที่ภายในหรือคลาส / ฟังก์ชั่น / ค่าคงที่ของบุคคลที่สาม เนมสเปซยังมีความสามารถในการนามแฝง (หรือย่อให้เล็กลง) Extra_Long_Names ที่ออกแบบมาเพื่อลดปัญหาแรกโดยปรับปรุงความสามารถในการอ่านของซอร์สโค้ด

อย่างที่เราทุกคนรู้กันว่าเนมสเปซและคุณสมบัติไม่ใช่ของใหม่ใน PHP แต่ก็ยังมีผู้พัฒนา php หลายคนที่ไม่ได้ใช้แนวคิดที่ยอดเยี่ยมเหล่านี้เนื่องจากความซับซ้อนของพวกเขา ดังนั้นในโพสต์นี้ ฉันจะพยายามล้างพวกเขาด้วยตัวอย่าง เนมสเปซและคุณลักษณะคืออะไร

คุณสามารถนำไปใช้ในโค้ดของคุณเพื่อทำให้โค้ดของคุณสามารถใช้ซ้ำได้และขยายได้

ประโยชน์ของเนมสเปซ

คุณสามารถใช้เนมสเปซเพื่อหลีกเลี่ยงการชนกันของชื่อระหว่างรหัสที่คุณสร้างและคลาส PHP / ฟังก์ชั่น / ค่าคงที่ภายในหรือคลาส / ฟังก์ชั่น / ค่าคงที่ของบุคคลที่สาม

เนมสเปซยังมีความสามารถในการนามแฝง (หรือย่อให้เล็กลง) Extra_Long_Names ที่ออกแบบมาเพื่อลดปัญหาแรกโดยปรับปรุงความสามารถในการอ่านของซอร์สโค้ด มาทำความเข้าใจกับเนมสเปซด้วยตัวอย่าง สร้างชื่อโฟลเดอร์“ php_oops” ใน htdocs (xampp) หรือ www (xwamp) สร้างโฟลเดอร์ใหม่ภายใต้ไดเรกทอรีรากชื่อ“ namespaces” แล้วสร้างไฟล์ index.php ภายใต้โฟลเดอร์เนมสเปซ

<?php
// FilePath:- namespaces/index.php

// let's say, we have two classes in index,
// here, these two classes have global space
class A 
{ 
   function __construct()
   { 
      echo "I am at Global space, Class A";
   }
}
class B
{
   function __construct()
   {
      echo "I am at Global space, Class B";
   }
}
// now create an object of class and 
$object = new A; // unqualified class name
echo "<br/>";
$object = new \B; // fully qualified class name
// output: 
I am at Global space, Class A
I am at Global space, Class B

การอ้างอิง - https://medium.com/@akgarg007/php-laravel-namespaces-and-traits-01-9540fe2969cb


1
โปรดใช้ความระมัดระวังกับการเชื่อมโยงไปยังเนื้อหาของคุณเองบนเว็บไซต์ต่าง ๆ ที่คุณไม่ต้องการที่จะเป็นผู้ส่งสแปม คุณควรรวมเนื้อหาส่วนใหญ่ไว้ที่นี่และใช้ลิงก์เป็นข้อมูลอ้างอิงเท่านั้น
Dharman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.