ก่อนหน้าที่จะมี PHP 8.0 เวลาที่เราต้องการเข้าถึง Method หรือ Property ของ Object ที่ร้อยเรียงกันเป็นทอด ๆ (Chaining) ยิ่งถ้าข้อมูลนั้นมาจาก Database หรือ API ที่มีโอกาสเป็น null เราจะต้องเขียนโค้ดตรวจสอบกันอย่างยาวเหยียดเพื่อความปลอดภัย
ตัวอย่างโค้ดแบบเดิม
// สมมติว่าเราต้องการชื่อประเทศของผู้ใช้งาน
$country = null;
if ($user !== null) {
$profile = $user->getProfile();
if ($profile !== null) {
$address = $profile->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
จะเห็นว่าโค้ดมีความซ้อนเป็นชั้น ๆ (Nested If) ดูรก และอ่านยากมาก หรือบางคนอาจจะเลี่ยงไปใช้แบบนี้
$country = ($user && $user->getProfile() && $user->getProfile()->getAddress())
? $user->getProfile()->getAddress()->country
: null;
ถึงจะสั้นลง แต่ก็ยังต้องเขียนซ้ำ ๆ และเสี่ยงต่อการพิมพ์ผิดอยู่ดี
พระเอกขี่ม้าขาว: Nullsafe Operator (?->)
ตั้งแต่ PHP 8.0 เป็นต้นมา เราสามารถยุบโค้ดด้านบนทั้งหมดให้เหลือเพียงแค่ บรรทัดเดียว ได้ด้วยการเติมเครื่องหมายคำถาม ? ไว้หน้าลูกศร -> ครับ
ตัวอย่างโค้ดแบบใหม่
$country = $user?->getProfile()?->getAddress()?->country;
มันทำงานยังไง?
กลไกของมันเข้าใจง่ายมากครับ PHP จะไล่เช็คจากซ้ายไปขวา
- เช็คว่า
$userเป็นnullไหม? ถ้าใช่ มันจะหยุดทำงานทันทีแล้วคืนค่าnullให้變數$country - ถ้า
$userไม่ใช่nullมันก็จะไปเช็ค$user->getProfile()ต่อ - ทำแบบนี้ไปเรื่อย ๆ จนสุดสาย
💡 ข้อดี: ถ้าตัวใดตัวหนึ่งในสาย (Chain) เป็น null โค้ดจะไม่พัง (ไม่เกิด Fatal Error) แต่จะส่งกลับเป็น null ทันที เรียกว่าเกิดกระบวนการ Short-circuiting
ความแตกต่างระหว่าง ?-> (Nullsafe) กับ ?? (Null Coalescing)
สองตัวนี้มักจะใช้คู่กัน แต่อย่าสับสนหน้าที่ของมันนะครับ
?->(Nullsafe): ใช้เพื่อ “ทางผ่าน” ในการเข้าถึง Property/Method ของ Object อย่างปลอดภัย (ถ้าเจอ null ให้หยุดเดินต่อ)??(Null Coalescing): ใช้เพื่อ “กำหนดค่า Default” ในกรณีที่ผลลัพธ์สุดท้ายเป็นnullหรือไม่มีอยู่จริง
การใช้งานร่วมกันแบบทรงพลัง
// ถ้าตรงไหนสักแห่งเป็น null ให้ระบุประเทศเป็น 'Unknown' แทน
$country = $user?->getProfile()?->getAddress()?->country ?? 'Unknown';
ข้อจำกัดที่ควรรู้ (Caveats)
แม้ ?-> จะเทพแค่ไหน แต่ก็มีข้อจำกัดที่ต้องระวังอยู่ 2 เรื่องหลัก ๆ ครับ
- ใช้กับ write operations (การเขียนค่า) ไม่ได้
เราใช้ Nullsafe เพื่อ “อ่านค่า” เท่านั้น ไม่สามารถใช้ฝั่งซ้ายของเครื่องหมายเท่ากับเพื่อเปลี่ยนค่าได้$user?->getProfile()?->address = 'Bangkok'; // ❌ ทำไม่ได้! จะเกิด Compile error
- ไม่ช่วยเรื่อง Array Key ที่ไม่มีอยู่จริง
Nullsafe ทำงานกับ Object เท่านั้น หากคุณพยายามใช้เข้าถึง Key ของ Array ที่ไม่มีอยู่ จะยังเกิด Warning เหมือนเดิม$data = ['user' => null]; // $data['user']?->profile; // ❌ อันนี้รอดเพราะตรวจสอบ object หลังชี้ไปที่ user // $data['profile']?->name; // ❌ อันนี้พังตั้งแต่ $data['profile'] แล้ว (Undefined array key)
สรุป
การมาของ Nullsafe Operator ช่วยให้โค้ด PHP ในปัจจุบันสะอาดขึ้น (Clean Code) อ่านง่ายขึ้น และลดโอกาสเกิดบั๊กประเภท Call to a member function on null ได้อย่างมหาศาล ถือเป็น Syntax Sugar ที่เปลี่ยนชีวิตนักพัฒนา PHP ให้มีความสุขขึ้นอย่างแท้จริงครับ!
อ่านเพิ่มเติม