รหัสต่อไปนี้:
<?php
class Type {
}
function foo(Type $t) {
}
foo(null);
?>
ล้มเหลวขณะใช้งาน:
PHP Fatal error: Argument 1 passed to foo() must not be null
เหตุใดจึงไม่อนุญาตให้ส่งผ่าน null เช่นเดียวกับภาษาอื่น ๆ
รหัสต่อไปนี้:
<?php
class Type {
}
function foo(Type $t) {
}
foo(null);
?>
ล้มเหลวขณะใช้งาน:
PHP Fatal error: Argument 1 passed to foo() must not be null
เหตุใดจึงไม่อนุญาตให้ส่งผ่าน null เช่นเดียวกับภาษาอื่น ๆ
คำตอบ:
PHP 7.1 หรือใหม่กว่า (เผยแพร่วันที่ 2 ธันวาคม 2559)
คุณสามารถประกาศตัวแปรที่จะอยู่null
กับไวยากรณ์นี้อย่างชัดเจน
function foo(?Type $t) {
}
สิ่งนี้จะส่งผลให้
$this->foo(new Type()); // ok
$this->foo(null); // ok
$this->foo(); // error
ดังนั้นหากคุณต้องการอาร์กิวเมนต์ที่เป็นทางเลือกคุณสามารถปฏิบัติตามอนุสัญญาได้Type $t = null
ในขณะที่ถ้าคุณต้องการให้อาร์กิวเมนต์ยอมรับทั้งสองnull
และประเภทของอาร์กิวเมนต์คุณสามารถทำตามตัวอย่างด้านบน
PHP 7.0 หรือเก่ากว่า
คุณต้องเพิ่มค่าเริ่มต้นเช่น
function foo(Type $t = null) {
}
ด้วยวิธีนี้คุณสามารถส่งผ่านค่า Null ได้
นี่คือเอกสารในส่วนในคู่มือเกี่ยวกับการประกาศประเภท :
ประกาศสามารถทำที่จะยอมรับค่าถ้าค่าเริ่มต้นของพารามิเตอร์ที่มีการตั้งค่า
NULL
NULL
function foo(Type $t)
เป็นสิ่งที่ดีมาก; ดูข้อมูลอ้างอิง Null: ข้อผิดพลาดพันล้านดอลลาร์
เริ่มต้นจาก PHP 7.1 มีประเภท nullableพร้อมใช้งานเนื่องจากทั้งสองประเภทฟังก์ชันและพารามิเตอร์ส่งคืน ชนิดที่?T
สามารถมีค่าของชนิดที่กำหนดหรือT
null
ดังนั้นฟังก์ชันของคุณอาจมีลักษณะเช่นนี้:
function foo(?Type $t)
{
}
ทันทีที่คุณสามารถทำงานกับ PHP 7.1 สัญกรณ์นี้ควรเป็นที่นิยมมากกว่าfunction foo(Type $t = null)
เพราะยังคงบังคับให้ผู้เรียกระบุอาร์กิวเมนต์สำหรับพารามิเตอร์$t
อย่างชัดเจน
ตามคำตอบอื่น ๆ ที่กล่าวถึงแล้วจะสามารถทำได้เฉพาะเมื่อคุณระบุnull
เป็นค่าเริ่มต้น
แต่วิธีแก้ปัญหาวัตถุที่เน้นความปลอดภัยและปลอดภัยที่สุดคือ NullObject :
interface FooInterface
{
function bar();
}
class Foo implements FooInterface
{
public function bar()
{
return 'i am an object';
}
}
class NullFoo implements FooInterface
{
public function bar()
{
return 'i am null (but you still can use my interface)';
}
}
การใช้งาน:
function bar_my_foo(FooInterface $foo)
{
if ($foo instanceof NullFoo) {
// special handling of null values may go here
}
echo $foo->bar();
}
bar_my_foo(new NullFoo);
NullFoo
แทนที่วิธีนามธรรมแม้ว่าพวกเขาจะไม่มีความหมาย (โดยนิยามของnull
)
if (something is null)
ตรวจสอบเนื่องจาก NullObject นั้นมีวัตถุประสงค์เพื่อครอบคลุมพฤติกรรมทั้งหมดของค่าที่ไม่มีอยู่และผู้ร่วมมือภายนอกไม่ควรสนใจว่าจะเป็น วัตถุนั้นไม่มีอยู่จริง (null) หรือไม่