PHP Namespaces ใน WordPress – คู่มือไร้สาระ

เผยแพร่แล้ว: 2018-10-16

เนมสเปซ PHP มีอายุเกือบสิบปี ใช่ ทศวรรษผ่านไปแล้ว (และใช่ คุณแก่แล้ว) แม้ว่าเวลาจะผ่านไปกว่าทศวรรษแล้วตั้งแต่เปิดตัว PHP v5.3 นักพัฒนาหลายคนยังไม่มีความเข้าใจพื้นฐานเกี่ยวกับเนมสเปซ จริงอยู่ที่ WordPress ไม่ได้ใช้เนมสเปซ ดังนั้น “ คุณไม่จำเป็นต้องรู้วิธีใช้เนมสเปซหากคุณทำงานกับ WordPress เท่านั้น” คุณไม่จำเป็นต้องเป็นนินจาเนมสเปซ แต่การทำความเข้าใจพื้นฐานนั้นง่ายและทำได้ดี

เนมสเปซ PHP มีมานานกว่าทศวรรษแล้ว แต่คุณยังคงไม่ได้ใช้มันเพราะ #wordpress ก็เช่นกันใช่หรือไม่ อ่านแล้วเริ่มใช้งานได้ภายใน 2 นาที! #การพัฒนา

คลิกเพื่อทวีต

เมื่อไม่มีการรองรับเนมสเปซ – ใช้คำนำหน้า

เป็นเวลานาน PHP ไม่ได้รับการรองรับเนมสเปซดั้งเดิม นั่นเป็นสาเหตุที่ WordPress และฐานโค้ดขนาดใหญ่อื่นๆ ไม่ได้ใช้เนมสเปซดั้งเดิม มันไม่ได้อยู่ใกล้เมื่อจำเป็น ดังนั้นจึงใช้คำนำหน้า

Namespacing มีความสำคัญเนื่องจากช่วยให้แน่ใจว่าฟังก์ชันของคุณ write_to_log() ยังไม่ได้กำหนดโดยโค้ดอื่น เพื่อหลีกเลี่ยงไม่ให้ชื่อขัดแย้งกันทุกอย่างในขอบเขตสากลจำเป็นต้องมีคำนำหน้าเพื่อให้ฟังก์ชันกลายเป็น awesome_project_write_to_log() และฟังก์ชันและตัวแปรอื่น ๆ ทั้งหมดจะได้รับคำนำหน้า awesome_project_ ด้วย เรียบง่าย? มันคือ! น่ารัก? ไม่แน่

มีทางเลือกอื่นสำหรับแนวทางดังกล่าว เช่น วิธีการห่อหุ้มด้วยวิธีสแตติก คุณรวมฟังก์ชันทั้งหมดไว้ในคลาสและประกาศให้เป็นเมธอดแบบสแตติก จากนั้นแทนที่จะเรียก my_function() คุณเรียก My_Class::my_function() ดีกว่า? เล็กน้อย แต่ก็ยังไม่ใช่เนมสเปซที่เหมาะสม

มาดูกันว่าเนมสเปซช่วยให้โค้ดหลายชิ้น (หรือแพ็กเกจหากต้องการ) ใช้ชื่อคลาสและฟังก์ชันเดียวกันโดยไม่มีข้อขัดแย้งได้อย่างไร หรือตามที่คู่มือ PHP บอก – วิธีเปิดใช้งานการห่อหุ้มโค้ด การเปรียบเทียบของพวกเขากับไฟล์และโฟลเดอร์นั้นยังปรากฏอยู่ - เนมสเปซมีพฤติกรรมเหมือนกับโฟลเดอร์ในหลายๆ ทาง ดังนั้นฉันจะคัดลอก/วางจากคู่มือนี้

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

ประกาศเนมสเปซ – จำบรรทัดแรก

namespace ของคีย์เวิร์ดจะต้องเป็นโค้ดบรรทัดแรกในไฟล์ (ไม่นับความคิดเห็นและเนื้อหาที่ไม่ใช่ PHP) เนมสเปซมีผลกับคลาส อินเตอร์เฟส ฟังก์ชัน และค่าคงที่เท่านั้น ไม่ส่งผลต่อตัวแปร คุณสามารถกำหนดเนมสเปซเดียวกันในไฟล์หลายไฟล์ได้ ทำให้คุณสามารถแยกโค้ดออกเป็นหลายไฟล์ได้ เนมสเปซย่อยอนุญาตให้กำหนดลำดับชั้นในเนมสเปซได้เหมือนกับในโฟลเดอร์โดยใช้แบ็กสแลช – namespace myproject\level1\level2 นี่เป็นกฎพื้นฐานและเกือบทั้งหมดสำหรับการประกาศเนมสเปซ

// file-A.php contains a function under the myCompany\PackageA namespace
namespace myCompany\PackageA;
 
function do_something() {
  // do things
}
// file-B.php contains a function with the same name
// but under a different namespace
namespace myCompany\PackageB;
 
function do_something() {
  // do things
}

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

// do not put multiple namespace declarations into the same file
// but if you must, here's the syntax

namespace MyFirstProject {
  const CONST = true;
  class Connection { /* ... */ }
  function connect() { /* ... */  }
}

namespace MySecondProject {
  const CONST = true;
  class Connection { /* ... */ }
  function connect() { /* ... */  }
}

// any code after this has to go in the global namespace
namespace {
  $some_var = 1;
  function_in_global_namespace();
}

การใช้เนมสเปซ – จำโฟลเดอร์

อย่างที่ฉันพูดไปแล้ว – เนมสเปซนั้นคล้ายกับโฟลเดอร์มาก สมมติว่าไฟล์ foo.txt อยู่ในโฟลเดอร์ปัจจุบันของคุณ คุณสามารถอ้างอิงได้ด้วย foo.txt อย่างง่าย หากคุณอยู่เหนือโฟลเดอร์หนึ่งระดับที่มีไฟล์ foo.txt คุณต้องใช้พาธสัมพัทธ์ ../foo.txt หรือหนึ่ง /folder1/folder2/foo.txt แบบสัมบูรณ์ ไม่มีอะไรแฟนซี เนมสเปซใช้กระบวนทัศน์เดียวกัน

// remember after declaring a namespace
// all our code is in it; like when you're working in a folder
namespace mycompany\project;

function foo() {}
class foo {
  static function staticmethod() {}
}

// resolves to mycompany\project\foo() because of line #3
foo();

// likewise, resolves to mycompany\project\foo::staticmethod()
foo::staticmethod();

// constant are affected by namespaces too
// so we're working with mycompany\project\FOO
echo FOO;

// this is a relative path
// resolves to mycompany\project\subnamespace\foo()
subnamespace\foo();

// static methods are no different
// mycompany\project\subnamespace\foo::staticmethod()
subnamespace\foo::staticmethod();
                                 
// a full namespace path starts with a backslash
// it resolves exactly to what it says it does
\otherNamespace\Bar\foo();

// again same thing for a constant, full path nothing magical
echo \otherNamespace\Bar\FOO;

ดูคีย์เวิร์ด use ในคู่มือ PHP – ตัวอย่างดีมาก มีวิธีการนำเข้าโค้ดจากเนมสเปซ PHP อื่น ๆ ไปยังเนมสเปซปัจจุบันหรือเพื่ออ้างถึงชื่อภายนอก (ที่มีคุณสมบัติครบถ้วน) ด้วยนามแฝง

ใช่ คุณต้องการเนมสเปซ & ควรใช้เนมสเปซ

เนื่องจากเห็นได้ชัดเจนจากการดูที่แหล่งที่มาของ WordPress คุณจึงไม่จำเป็นต้องใช้เนมสเปซ แต่คุณต้องใช้วิธีการบางอย่างในการเนมสเปซ นำหน้าด้วย wp_ ในกรณีของ WP ถ้าเราทำอยู่แล้วทำไมไม่ทำอย่างถูกต้อง?

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

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