DevTips – เนมสเปซใน PHP
เผยแพร่แล้ว: 2020-03-06ประมาณหนึ่งปีที่แล้ว WordPress ตัดสินใจอัปเดตเวอร์ชัน PHP ขั้นต่ำที่จำเป็น จาก 5.2 (ใช้มาตั้งแต่ปี 2010) เป็นเวอร์ชันล่าสุด อันที่จริง วันนี้ PHP เวอร์ชันขั้นต่ำที่แนะนำโดย WordPress เป็นหนึ่งในเวอร์ชันล่าสุด: PHP 7.3
หากคุณเป็นผู้ใช้ WordPress ธรรมดา สิ่งนี้อาจไม่ส่งผลกระทบต่อคุณมากนัก (นอกเหนือจากข้อเท็จจริงที่ว่าเวอร์ชันใหม่เหล่านี้ให้ประสิทธิภาพที่ดีกว่า)
แต่ถ้าคุณเป็นนักพัฒนา เวอร์ชัน PHP ใหม่เหล่านี้มีคุณสมบัติที่ยอดเยี่ยมที่คุณสามารถใช้ในปลั๊กอินและธีมของคุณได้ และวันนี้โดยเฉพาะอย่างยิ่ง ฉันต้องการจะพูดคุยกับคุณเกี่ยวกับสิ่งหนึ่งที่อยู่กับเรามาเป็นเวลานาน แต่: เนมสเปซ
คำนำหน้า WordPress และโค้ด
กฎข้อแรกที่คุณเรียนรู้ในฐานะนักพัฒนา WordPress คือ "ใช้คำนำหน้าในทุกสิ่งที่เราทำ" เพื่อหลีกเลี่ยง "ชื่อที่ขัดแย้งกัน" ตามที่เราสามารถอ่านได้ในแนวทางปฏิบัติที่ดีที่สุดของ WordPress :
การชนกันของการตั้งชื่อเกิดขึ้นเมื่อปลั๊กอินของคุณใช้ชื่อเดียวกันสำหรับตัวแปร ฟังก์ชัน หรือคลาสเป็นปลั๊กอินอื่น
[เพื่อหลีกเลี่ยงการชนกันของชื่อ] ตัวแปร ฟังก์ชันและคลาสทั้งหมดควรนำหน้าด้วยตัวระบุที่ไม่ซ้ำกัน คำนำหน้าป้องกันไม่ให้ปลั๊กอินอื่นเขียนทับตัวแปรของคุณและเรียกใช้ฟังก์ชันและคลาสของคุณโดยไม่ได้ตั้งใจ มันจะป้องกันไม่ให้คุณทำเช่นเดียวกัน
แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาปลั๊กอิน WordPress
ตัวอย่างเช่น แทนที่จะสร้างฟังก์ชันเช่น get_site_id จะดีกว่าที่จะตั้งชื่อมันว่า nelio_content_get_site_id ด้วยวิธีนี้ เราสามารถระบุปลั๊กอิน ( nelio_content ) หรือธีมที่มีฟังก์ชันบางอย่าง ( get_site_id ) ได้อย่างรวดเร็ว และหลีกเลี่ยงข้อผิดพลาดร้ายแรงหากมีปลั๊กอินหลายตัวพยายามกำหนดฟังก์ชันเดียวกัน
การใช้คำนำหน้าเป็นวิธีพื้นฐานในการสร้าง "เนมสเปซ" วิธีแก้ปัญหาที่เราต้องใช้เมื่อเราไม่มีทางเลือกอื่นที่ดีกว่า องค์ประกอบทั้งหมดที่ใช้คำนำหน้าเดียวกันเป็นส่วนหนึ่งของชุดหรือเนมสเปซเดียวกัน แต่สิ่งนี้ส่งผลให้โค้ดซับซ้อนขึ้นโดยไม่จำเป็น: ชื่อยาวขึ้นเนื่องจากคำนำหน้าที่ไม่มีจุดประสงค์อื่นนอกจากการจำลองเนมสเปซ
PHP เนมสเปซ
PHP เวอร์ชัน 5.3 แนะนำแนวคิดของ เนมสเปซ คำจำกัดความที่พวกเขาให้ไว้ในเอกสารประกอบถือว่ายอดเยี่ยมสำหรับฉัน ดังนั้นฉันจึงทำซ้ำที่นี่:
ในเนมสเปซที่มีคำจำกัดความกว้างที่สุดเป็นวิธีการห่อหุ้มรายการ ซึ่งถือได้ว่าเป็นแนวคิดที่เป็นนามธรรมในหลาย ๆ ที่ ตัวอย่างเช่น ในไดเร็กทอรีระบบปฏิบัติการใด ๆ ที่ทำหน้าที่จัดกลุ่มไฟล์ที่เกี่ยวข้อง และทำหน้าที่เป็นเนมสเปซสำหรับไฟล์ที่อยู่ภายใน จากตัวอย่างที่เป็นรูปธรรม ไฟล์ foo.txt สามารถมีอยู่ในทั้งไดเร็กทอรี /home/greg และใน /home/other แต่ foo.txt สองสำเนาไม่สามารถอยู่ร่วมกันในไดเร็กทอรีเดียวกันได้
ในโลกของ PHP เนมสเปซได้รับการออกแบบมาเพื่อแก้ปัญหาสองประการที่ผู้เขียนไลบรารีและแอปพลิเคชันพบเมื่อสร้างองค์ประกอบโค้ดที่นำกลับมาใช้ใหม่ได้ เช่น คลาสหรือฟังก์ชัน:
1. ชื่อขัดแย้งกันระหว่างรหัสที่คุณสร้างและรหัส PHP ภายในหรือรหัสบุคคลที่สาม
2. ความสามารถในการนามแฝง (หรือย่อ) Extra_Long_Names ปรับปรุงความสามารถในการอ่านซอร์สโค้ด
เอกสาร PHP
วิธีสร้างเนมสเปซ
การสร้างเนมสเปซใน PHP นั้นง่ายมาก ที่จุดเริ่มต้นของไฟล์ PHP ที่คุณสร้าง ให้เพิ่มคำสั่ง namespace ที่มีชื่อที่คุณต้องการใช้ และ “ทุกอย่าง” ที่คุณกำหนดในไฟล์นั้นจะเป็นของเนมสเปซนั้น:
<?php namespace Nelio_Content; ใช่ มันง่ายมาก! ตอนนี้ “ทุกอย่าง” ที่เราสร้างจะมีในเนมสเปซ Nelio_Content ตัวอย่างเช่น ถ้าฉันกำหนดฟังก์ชันเหมือนที่ฉันกล่าวถึงในตอนต้น:
<?php namespace Nelio_Content; function get_site_id() { // ... } ตอนนี้เรารู้แล้วว่า get_site_id อยู่ในเนมสเปซ Nelio_Content ด้วยวิธีนี้ เราไม่จำเป็นต้องใช้คำนำหน้า nelio_content_ เมื่อกำหนดฟังก์ชันอีกต่อไป ยอดเยี่ยม!
ข้อยกเว้นสำหรับเนมสเปซ
หากคุณดูสิ่งที่ฉันบอกคุณจนถึงตอนนี้ คุณจะเห็นว่าฉันเขียน "ทุกอย่าง" ด้วยเครื่องหมายคำพูด: "'ทุกอย่าง' ที่เราเพิ่มเข้าไปจะเป็นของเนมสเปซที่ระบุ ทำไมฉันถึงทำอย่างนั้น? เนื่องจากเนมสเปซใช้ไม่ได้กับโค้ดทั้งหมดที่เราเขียน... มีข้อยกเว้นบางประการ
เนมสเปซ PHP ครอบคลุมองค์ประกอบ PHP ต่อไปนี้เท่านั้น:
- ชั้นเรียน
- อินเทอร์เฟซ
- ลักษณะนิสัย
- ฟังก์ชั่น
- ค่าคงที่ประกาศด้วย
constแต่ไม่ใช่ด้วยdefine
นอกจากนี้ ยังมีบางสิ่งเพิ่มเติมใน WordPress ที่ต้องการเนมสเปซของตัวเอง และขออภัย เนมสเปซ PHP ไม่ครอบคลุม: สคริปต์ของคุณ จัดการ ตัวเลือกฐานข้อมูล หรือประเภทเนื้อหาที่กำหนดเองและข้อมูลเมตา ฯลฯ ในทุกกรณี คุณต้อง ดำเนินการต่อโดยใช้คำนำหน้า

วิธีการนำเข้าองค์ประกอบจากเนมสเปซหนึ่งไปยังอีกเนมสเปซ
หากคุณต้องการใช้องค์ประกอบที่อยู่ในเนมสเปซของคุณเอง คุณไม่จำเป็นต้องดำเนินการใดๆ เป็นพิเศษ แค่เรียกชื่อองค์ประกอบนั้น ตัวอย่างเช่น ในข้อมูลโค้ดต่อไปนี้:
<?php namespace Nelio_Content; function get_site_id() { // ... } function get_auth_token() { $site_id = get_site_id(); // ... } คุณจะเห็นว่าเราได้กำหนดฟังก์ชันไว้สองฟังก์ชัน: get_site_id และ get_auth_token ทั้งสองอย่างภายในเนมสเปซ Nelio_Content เมื่อ get_auth_token ต้องใช้ get_site_id มันก็เรียกตามปกติ
ในทางกลับกัน หากคุณจำเป็นต้องใช้ get_site_id ในเนมสเปซอื่น คุณต้องเรียกใช้ฟังก์ชันโดยใช้ตัวระบุแบบเต็ม:
<?php namespace Something_Else; function do_some_action() { $site_id = Nelio_Content\get_site_id(); // ... } หรือคุณต้องนำเข้าฟังก์ชันด้วยคำสำคัญ use :
<?php namespace Something_Else; use Nelio_Content\get_site_id; function do_some_action() { $site_id = get_site_id(); // ... } โดยส่วนตัวแล้วฉันชอบตัวเลือกที่สองมาก: การ use คำหลักเพื่อนำเข้าฟังก์ชันจากเนมสเปซอื่น คุณสามารถดูส่วนหัวของไฟล์ได้อย่างรวดเร็วและระบุการขึ้นต่อกันของไฟล์
ตัวกรองและการดำเนินการของ WordPress ด้วย PHP Namespaces
มีรายละเอียดสำคัญที่คุณควรจำไว้เมื่อใช้เนมสเปซถัดจากตัวกรองและการดำเนินการของ WordPress เมื่อคุณระบุการเรียกกลับของตัวกรองและการดำเนินการ โดยปกติคุณจะทำได้โดยระบุชื่อการโทรกลับเป็นสตริง:
<?php // ... add_action( 'init', 'do_some_action' );ปัญหาคือถ้าฟังก์ชันนี้อยู่ภายในเนมสเปซ hook ก่อนหน้าจะไม่ทำงานตามที่คาดไว้ คุณต้องบอก WordPress ถึงชื่อเต็มของฟังก์ชัน กล่าวอีกนัยหนึ่ง คุณต้องรวมเนมสเปซของมันด้วย (ถ้ามี)
คุณกำลังเพิ่ม hook ในไฟล์ที่คุณกำหนดเนมสเปซเองหรือไม่? ไม่เป็นไร ใช้ชื่อเต็ม:
<?php namespace Nelio_Content; function do_some_action() { // ... } add_action( 'init', 'Nelio_Content\do_some_action' ); คุณอยู่ในเนมสเปซอื่น แต่คุณนำเข้าฟังก์ชันด้วย use หรือไม่ ไม่เป็นไร ใช้ชื่อเต็ม:
<?php namespace Something_Else; use Nelio_Content\do_some_action; // ... add_action( 'init', 'Nelio_Content\do_some_action' );การใช้นามแฝงกับเนมสเปซของเรา
ฟังก์ชันที่น่าสนใจอีกอย่างของเนมสเปซคือการใช้นามแฝง ลองนึกภาพสถานการณ์ต่อไปนี้:
<?php namespace Nelio_Content; function get_site_id() { // ... } ถ้าฉันต้องการใช้ฟังก์ชันนี้ในเนมสเปซอื่น เราได้เห็นแล้วว่า ฉันสามารถทำได้โดย use แต่ฉันจะใช้ฟังก์ชันนี้ได้อย่างไรถ้าโมดูลที่ฉันต้องการใช้มีฟังก์ชันที่เรียกว่า get_site_id อยู่แล้ว
โชคดีสำหรับฉัน เราสามารถเรียกชื่อแทนการนำเข้าของเราเป็นชื่อใหม่ได้:
<?php namespace Something_Else; use Nelio_Content\get_site_id as get_nc_site_id(); function get_site_id() { // ... } function do_some_action() { $nc_site_idd = get_nc_site_id(); // ... }เริ่มใช้เนมสเปซวันนี้!
เนมสเปซเป็นเครื่องมือที่ยอดเยี่ยมในการหลีกเลี่ยงการชนกันของชื่อและเพื่อจัดระเบียบโค้ดของเรา อันที่จริงแล้วแม้ว่าฉันจะไม่ได้แสดงความคิดเห็นในโพสต์นี้ แต่ก็มีมาตรฐานเช่น PSR-4 ที่อนุญาตให้ PHP โหลดคลาสอัตโนมัติตามโครงสร้างของเนมสเปซที่คุณใช้และวิธีที่คุณจัดระเบียบโค้ดลงในไดเร็กทอรีและไฟล์
หากคุณยังไม่ได้ใช้เนมสเปซในโปรเจ็กต์ของคุณ เราขอแนะนำให้คุณเริ่มดำเนินการตั้งแต่บัดนี้เป็นต้นไป บอกเราเกี่ยวกับประสบการณ์ของคุณในความคิดเห็น!
ภาพเด่นโดย Chaitanya Tvs บน Unsplash
