ผู้ประกอบการที่สาม PHP เทียบกับผู้ประกอบการรวม null


342

บางคนสามารถอธิบายความแตกต่างระหว่างตัวดำเนินการแบบไตรภาค shorthand ( ?:) และตัวดำเนินการรวมค่า null ( ??) ใน PHP ได้หรือไม่?

เมื่อไหร่ที่พวกเขาประพฤติแตกต่างกันและเมื่อในลักษณะเดียวกัน (ถ้าเป็นเช่นนั้น)

$a ?: $b

VS.

$a ?? $b

คำตอบ:


345

เมื่ออาร์กิวเมนต์แรกของคุณเป็นโมฆะมันจะเหมือนกันโดยทั่วไปยกเว้นว่าการรวมกันเป็นโมฆะจะไม่ส่งออกE_NOTICEเมื่อคุณมีตัวแปรที่ไม่ได้กำหนด PHP 7.0 เอกสารการย้ายถิ่นได้นี้จะพูดว่า:

ตัวดำเนินการรวมศูนย์ว่าง (??) ได้รับการเพิ่มเป็นน้ำตาลเชิงประโยคสำหรับกรณีทั่วไปที่จำเป็นต้องใช้ ternary ร่วมกับ isset () มันจะส่งกลับตัวถูกดำเนินการแรกถ้ามันมีอยู่และไม่เป็นโมฆะ; มิฉะนั้นจะส่งคืนตัวถูกดำเนินการที่สอง

นี่คือตัวอย่างรหัสที่จะสาธิต:

<?php

$a = null;

print $a ?? 'b'; // b
print "\n";

print $a ?: 'b'; // b
print "\n";

print $c ?? 'a'; // a
print "\n";

print $c ?: 'a'; // Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";

$b = array('a' => null);

print $b['a'] ?? 'd'; // d
print "\n";

print $b['a'] ?: 'd'; // d
print "\n";

print $b['c'] ?? 'e'; // e
print "\n";

print $b['c'] ?: 'e'; // Notice: Undefined index: c in /in/apAIb on line 33
print "\n";

เส้นที่มีการแจ้งให้ทราบนั้นเป็นสิ่งที่ฉันใช้ตัวดำเนินการแบบย่อและสั้นซึ่งต่างจากตัวดำเนินการรวมตัวที่ว่าง อย่างไรก็ตามแม้จะมีการแจ้งเตือน PHP จะให้การตอบกลับแบบเดียวกัน

เรียกใช้งานโค้ด: https://3v4l.org/McavC

nullของหลักสูตรนี้อยู่เสมอสมมติว่าอาร์กิวเมนต์แรกคือ เมื่อมันไม่ null อีกต่อไปแล้วคุณจะจบลงด้วยความแตกต่างในการที่??ผู้ประกอบการมักจะกลับอาร์กิวเมนต์แรกในขณะที่?:ชวเลขจะเฉพาะในกรณีที่อาร์กิวเมนต์แรกเป็น truthy และที่อาศัยวิธีPHP จะพิมพ์หล่อสิ่งที่บูล

ดังนั้น:

$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'

ก็จะมี$aเท่ากับfalseและเท่ากับ$b'g'


8
เคล็ดลับ: ถ้าคุณใช้อยู่ ?? แทนที่จะเป็น?: แต่ถ้าอย่างนั้นคุณต้องทำให้โค้ดของคุณใช้งานได้กับ PHP เวอร์ชันเก่ากว่า 7 (สำหรับปลั๊กอินสำหรับอดีต) จากนั้นคุณอาจต้องการสลับออกเป็น ?? กับ isset ($ อย่าง) $ something: $ something_else ทุกที่ในรหัสของคุณ คุณสามารถทำได้ด้วย Notepad ++ หรือ nedit (และบรรณาธิการอื่น ๆ ด้วย) โดยใช้เครื่องมือค้นหา / แทนที่เลือกตัวเลือกนิพจน์ทั่วไปและแทรกในฟิลด์ค้นหา: "\ s * (\ S +) \ s * \? \?" และในช่องแทนที่: "isset ($ 1)? $ 1:" โดยไม่มีเครื่องหมายอัญประกาศ (nedit ใช้ \ 1 แทน $ 1) จากนั้นแทนที่ทั้งหมด
Damian Green

14
นี่คือคำตอบที่ถูกต้อง แต่การตรวจสอบความจริงคือความแตกต่างที่สำคัญและควรเน้นมากขึ้น
mancze

2
@MasterOdin ไม่พอใจกับคำตอบของคุณ ทั้งสองไม่เหมือนกัน มีผลต่างกัน
อยากรู้อยากเห็น

1
เป็นที่น่าสังเกตว่าคุณสามารถใช้? ด้วยการผูกมัด ตัวอย่างเช่น: $b = []; var_dump($b['a']['b']['c'] ?? 'default');หรือกับวัตถุ$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
Jack B

$a = [];โปรดทราบว่าการทำงานยังแตกต่างกันด้วย ดู: 3v4l.org/iCCa0
Soullivaneuh

75

เรียกใช้ด้านล่างในโหมดโต้ตอบ php ( php -aบนเทอร์มินัล) ความคิดเห็นในแต่ละบรรทัดแสดงผลลัพธ์

var_dump (false ?? 'value2');   # bool(false)
var_dump (true  ?? 'value2');   # bool(true)
var_dump (null  ?? 'value2');   # string(6) "value2"
var_dump (''    ?? 'value2');   # string(0) ""
var_dump (0     ?? 'value2');   # int(0)

var_dump (false ?: 'value2');   # string(6) "value2"
var_dump (true  ?: 'value2');   # bool(true)
var_dump (null  ?: 'value2');   # string(6) "value2"
var_dump (''    ?: 'value2');   # string(6) "value2"
var_dump (0     ?: 'value2');   # string(6) "value2"

ดังนั้นนี่คือการตีความของฉัน:

1. ผู้ประกอบการ Null Coalescing - ??:

  • ??เป็นเหมือน "ประตู" ที่อนุญาตให้ NULL ผ่านเท่านั้น
  • ดังนั้นมันก็จะส่งกลับพารามิเตอร์แรกเว้นแต่พารามิเตอร์แรกที่จะเกิดขึ้น NULL
  • วิธี??นี้เหมือนกับ( !isset() || is_null() )

2. ผู้ประกอบการที่สาม - ?:

  • ?:เปรียบเหมือนประตูที่ปล่อยanything falsyผ่าน - รวมทั้งNULL
  • 0, empty string, NULL, false, !isset(), empty().. อะไรที่มีกลิ่น falsy
  • เช่นเดียวกับผู้ประกอบการที่คลาสสิก: echo ($x ? $x : false)
  • หมายเหตุ: ?:จะโยนตัวแปรที่PHP NOTICEไม่ได้กำหนด ( unsetหรือ!isset())

3. ดังนั้นหมอฉันจะใช้เมื่อไหร่??และ?:..

  • ฉันแค่ล้อเล่น - ฉันไม่ใช่แพทย์และนี่เป็นเพียงการตีความ
  • ฉันจะใช้?:เมื่อ
    • ทำการempty($x)ตรวจสอบ
    • การดำเนินการประกอบไปด้วยคลาสสิกเช่น!empty($x) ? $x : $yสามารถสั้นลงไป$x ?: $y
    • if(!$x) { fn($x); } else { fn($y); } สามารถตัดให้สั้นลง fn(($x ?: $y))
  • ฉันจะใช้??เมื่อ
    • ฉันต้องการ!isset() || is_null()ตรวจสอบ
    • เช่นตรวจสอบว่ามีวัตถุอยู่หรือไม่ - $object = $object ?? new objClassName();

4. ผู้ประกอบการซ้อน ...

  1. ผู้ประกอบการ Ternary สามารถซ้อน ...

    echo 0 ?: 1 ?: 2 ?: 3; //1
    echo 1 ?: 0 ?: 3 ?: 2; //1
    echo 2 ?: 1 ?: 0 ?: 3; //2
    echo 3 ?: 2 ?: 1 ?: 0; //3
    
    echo 0 ?: 1 ?: 2 ?: 3; //1
    echo 0 ?: 0 ?: 2 ?: 3; //2
    echo 0 ?: 0 ?: 0 ?: 3; //3

    แหล่งที่มาและเครดิตสำหรับรหัสนี้

    นี่เป็นลำดับของ:

    if( truthy ) {}
    else if(truthy ) {}
    else if(truthy ) {}
    ..
    else {}
  2. ตัวดำเนินการ Null Coalese สามารถซ้อน ...

    $v = $x ?? $y ?? $z; 

    นี่คือลำดับของ:

    if(!isset($x) || is_null($x) ) {} 
    else if(!isset($y) || is_null($y) ) {}
    else {}
  3. ใช้การซ้อนฉันสามารถย่อ:

    if(!isset($_GET['name'])){
       if($user_name){
          $name = $user_name;
       }else {
          $name = 'anonymous';
       }
    } else { 
       $name = $_GET['name'];
    }

    สำหรับสิ่งนี้:

    $name = $_GET['name'] ?? $user_name ?: 'anonymous';

    เจ๋งใช่มั้ย :-)


3
โดยคำตอบที่ดีที่สุด
Faizan Anwer Ali Rupani

69

หากคุณใช้ผู้ประกอบการทางลัดแบบนี้มันจะทำให้เกิดการแจ้งเตือนหาก$_GET['username']ไม่ได้ตั้ง:

$val = $_GET['username'] ?: 'default';

ดังนั้นคุณต้องทำสิ่งนี้แทน:

$val = isset($_GET['username']) ? $_GET['username'] : 'default';

ตัวดำเนินการรวมศูนย์ว่างเทียบเท่ากับคำสั่งด้านบนและจะส่งคืน 'ค่าเริ่มต้น' หาก$_GET['username']ไม่ได้ตั้งค่าหรือเป็นnull:

$val = $_GET['username'] ?? 'default';

โปรดทราบว่ามันไม่ได้ตรวจสอบความจริง มันตรวจสอบเฉพาะในกรณีที่มีการตั้งค่าและไม่เป็นโมฆะ

คุณสามารถทำเช่นนี้ได้และจะส่งคืนค่าที่กำหนดไว้ ( แรกและไม่null):

$val = $input1 ?? $input2 ?? $input3 ?? 'default';

ตอนนี้เป็นตัวดำเนินการรวมที่เหมาะสม


42

ความแตกต่างที่สำคัญคือ

  1. ประกอบไปด้วยผู้ประกอบการแสดงออกของ expr1 ?: expr3ผลตอบแทนexpr1หากexpr1ประเมิน TRUEแต่ในมืออื่น ๆNull หลอมรวมผู้ประกอบการแสดงออก (expr1) ?? (expr2) ประเมินexpr1ถ้าexpr1เป็นไม่ได้ NULL

  2. ประกอบไปด้วยผู้ประกอบการ expr1 ?: expr3ปล่อยแจ้งให้ทราบล่วงหน้าถ้าค่าด้านซ้าย(expr1) ไม่ได้อยู่ แต่ในมืออื่น ๆNull หลอมรวมผู้ประกอบการ (expr1) ?? (expr2)โดยเฉพาะอย่างยิ่งไม่ปล่อยแจ้งให้ทราบล่วงหน้าถ้าค่าด้านซ้ายไม่ได้อยู่เช่นเดียวกับ (expr1) isset()

  3. TernaryOperatorไม่มีการเชื่อมโยง

    ((true ? 'true' : false) ? 't' : 'f');

    ผู้ประกอบการ Null Coalescingมีความสัมพันธ์ที่ถูกต้อง

    ($a ?? ($b ?? $c));

ตอนนี้ให้อธิบายความแตกต่างระหว่างตัวอย่าง:

ผู้ประกอบการที่สาม (?:)

$x='';
$value=($x)?:'default';
var_dump($value);

// The above is identical to this if/else statement
if($x){
  $value=$x;
}
else{
  $value='default';
}
var_dump($value);

Null Coalescing Operator (??)

$value=($x)??'default';
var_dump($value);

// The above is identical to this if/else statement
if(isset($x)){
  $value=$x;
}
else{
  $value='default';
}
var_dump($value);

นี่คือตารางที่อธิบายความแตกต่างและความคล้ายคลึงกันระหว่าง'??'และ?:

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุพิเศษ: ตัวดำเนินการรวมศูนย์โมฆะและตัวดำเนินการที่ประกอบไปด้วยสามคือนิพจน์และมันไม่ได้ประเมินกับตัวแปร แต่เป็นผลของการแสดงออก สิ่งนี้สำคัญที่ต้องทราบว่าคุณต้องการส่งคืนตัวแปรโดยการอ้างอิงหรือไม่ คำสั่งส่งคืน $ foo หรือไม่ $ บาร์; และส่งคืน $ var == 42? $ a: $ b; ในฟังก์ชั่น return-by-Reference จะไม่ทำงานและมีการออกคำเตือน


15

ทั้งคู่มีพฤติกรรมแตกต่างกันเมื่อพูดถึงการจัดการข้อมูลแบบไดนามิก

หากตัวแปรว่างเปล่า ('') การรวมค่า null จะถือว่าตัวแปรนั้นเป็นจริง แต่ตัวดำเนินการแบบย่อจะไม่ดำเนินการใด ๆ และนั่นคือสิ่งที่ต้องคำนึงถึง

$a = NULL;
$c = '';

print $a ?? '1b';
print "\n";

print $a ?: '2b';
print "\n";

print $c ?? '1d';
print "\n";

print $c ?: '2d';
print "\n";

print $e ?? '1f';
print "\n";

print $e ?: '2f';

และผลลัพธ์:

1b
2b

2d
1f

Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f

ลิงก์: https://3v4l.org/ZBAa1


นี่เป็นตัวนับที่ชัดเจนว่าเข้าใจง่ายสำหรับ PHP โดยที่สตริงว่างมักจะถือว่าเป็นเท็จ แต่มันถูกระบุไว้อย่างชัดเจนในเอกสารสำหรับ ??: It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
Simon

12

ทั้งคู่เป็นชวเลขเพื่อการแสดงออกที่ยาวขึ้น

?:$a ? $a : $bสั้นสำหรับ สำนวนนี้จะประเมินถึง $ ถ้า $ a ประเมินTRUE

??isset($a) ? $a : $bสั้นสำหรับ นิพจน์นี้จะประเมินเป็น $ a หากมีการตั้งค่า $ a และไม่ใช่ค่าว่าง

กรณีการใช้ของพวกเขาทับซ้อนกันเมื่อ $ a ไม่ได้กำหนดหรือเป็นโมฆะ เมื่อ $ a ไม่ได้ถูกกำหนด??จะไม่สร้าง E_NOTICE แต่ผลลัพธ์จะเหมือนกัน เมื่อ $ a เป็นโมฆะผลลัพธ์จะเหมือนกัน


5

สำหรับผู้เริ่มต้น:

ตัวดำเนินการรวมศูนย์ Null (??)

ทุกอย่างเป็นจริงยกเว้นnullค่าและไม่ได้กำหนดไว้ (แอตทริบิวต์ตัวแปร / แถวลำดับ / วัตถุ)

อดีต:

$array = [];
$object = new stdClass();

var_export (false ?? 'second');                           # false
var_export (true  ?? 'second');                           # true
var_export (null  ?? 'second');                           # 'second'
var_export (''    ?? 'second');                           # ""
var_export ('some text'    ?? 'second');                  # "some text"
var_export (0     ?? 'second');                           # 0
var_export ($undefinedVarible ?? 'second');               # "second"
var_export ($array['undefined_index'] ?? 'second');       # "second"
var_export ($object->undefinedAttribute ?? 'second');     # "second"

นี้เป็นพื้นตรวจสอบตัวแปร (ดัชนีอาร์เรย์แอตทริบิวต์วัตถุ .. ฯลฯ ) nullเป็นที่มีอยู่และไม่ได้ คล้ายกับissetฟังก์ชั่น

ผู้ประกอบการที่สามจดชวเลข (? :)

ทุกสิ่งที่เป็นเท็จ ( false, null, 0, สตริงว่าง) จะมาเป็นเท็จ แต่ถ้ามันเป็นไม่ได้กำหนดก็ยังมาเป็นเท็จ แต่Noticeจะโยน

อดีต

$array = [];
$object = new stdClass();

var_export (false ?: 'second');                           # "second"
var_export (true  ?: 'second');                           # true
var_export (null  ?: 'second');                           # "second"
var_export (''    ?: 'second');                           # "second"
var_export ('some text'    ?? 'second');                  # "some text"
var_export (0     ?: 'second');                           # "second"
var_export ($undefinedVarible ?: 'second');               # "second" Notice: Undefined variable: ..
var_export ($array['undefined_index'] ?: 'second');       # "second" Notice: Undefined index: ..
var_export ($object->undefinedAttribute ?: 'second');     # "Notice: Undefined index: ..

หวังว่านี่จะช่วยได้


4

เลื่อนลงไปที่ลิงค์นี้และดูส่วนมันจะให้ตัวอย่างเปรียบเทียบที่แสดงด้านล่าง:

<?php
/** Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist. **/
$username = $_GET['user'] ?? 'nobody';
/** This is equivalent to: **/
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

/** Coalescing can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'. **/
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

อย่างไรก็ตามไม่ควรเชื่อมโยงตัวดำเนินการเนื่องจากทำให้เข้าใจรหัสได้ยากขึ้นเมื่ออ่านในภายหลัง

ตัวดำเนินการรวมศูนย์ว่าง (??) ได้รับการเพิ่มเป็นน้ำตาลเชิงประโยคสำหรับกรณีทั่วไปที่จำเป็นต้องใช้ ternary ร่วมกับ isset () มันจะส่งกลับตัวถูกดำเนินการแรกถ้ามันมีอยู่และไม่เป็นโมฆะ; มิฉะนั้นจะส่งคืนตัวถูกดำเนินการที่สอง

โดยพื้นฐานแล้วการใช้ตัวดำเนินการรวมกันจะทำให้การตรวจสอบอัตโนมัติเป็นโมฆะไม่เหมือนกับตัวดำเนินการแบบไตรภาค


1
โปรดอย่าพิจารณาการผูกมัด ... มันยากที่จะอ่าน / ทำความเข้าใจเหมือนไตรภาคที่ถูกล่ามโซ่
Mark Baker

7
@MarkBaker บุคคลที่ถูกล่ามโซ่ยากที่จะเข้าใจเพราะ PHP ได้ทำลายการเชื่อมโยงแบบสามส่วน สิ่งนี้ใช้ไม่ได้กับโอเปอเรเตอร์ coalesce และ imho chales coalesce นั้นเข้าใจได้อย่างสมบูรณ์
NikiC

7
ฉันไม่เห็นด้วย. การผูกมัด null เข้าด้วยกันเป็นคุณสมบัติที่ยอดเยี่ยมและไม่ทำให้อ่านยากหากคุณเข้าใจผู้ปฏิบัติงาน มันใช้กันทั่วไปใน javascript และเมื่อผู้คนคุ้นเคยกับมันใน PHP การโทรนี้ไม่ควรใช้การผูกมัดควรหยุด สิ่งที่ยากต่อการอ่านเป็นเรื่องยาก แต่การรวมตัวกันเป็นเรื่องง่าย เมื่อคุณอ่านจากซ้ายไปขวาจะแสดงรายการค่าที่ควรใช้ถัดไป
earl3s

2
ลักษณะนี้มากเช่นที่พบa || b || cในรูปแบบ JS ยกเว้นของ PHP สามารถใช้สำหรับการบูลีน ( false || 2ใน JS เป็น 2; false ?? 2ใน PHP เป็นเท็จ)
fregante

1
ฉันไม่เห็นด้วยกับคุณและคนอื่น ๆ เกี่ยวกับการไม่ใช้การผูกมัด มันเหมือนกับว่าไม่ต้องใช้ลูปเพราะอาจไม่เข้าใจ นักพัฒนา / ผู้เขียนโค้ดมีอิสระอย่างสมบูรณ์ในการใช้มาตรฐานการเข้ารหัสและการปฏิบัติที่พวกเขาเข้าใจแม้ว่าคนอื่นจะไม่ทำก็ตาม โดยส่วนตัวแล้วฉันมองว่าการรวมกลุ่มที่มีลักษณะคล้ายกันมากกับการสลับคำสั่ง ส่งคืนค่าแรกที่พบ (ชุด) และค่าสุดท้ายหากไม่พบสิ่งใด
kurdtpage

3

คำตอบอื่น ๆ จะไปลึกและให้คำอธิบายที่ดี สำหรับผู้ที่มองหาคำตอบด่วน

$a ?: 'fallback' คือ $a ? $a : 'fallback'

ในขณะที่

$a ?? 'fallback' คือ $a = isset($a) ? $a : 'fallback'


ความแตกต่างที่สำคัญคือเมื่อตัวดำเนินการด้านซ้ายเป็น:

  • ค่า falsy ที่ไม่ null ( 0, '', false, [], ... )
  • ตัวแปรที่ไม่ได้กำหนด

ไม่ควรมีในการขยายตัวดังกล่าวข้างต้น $a = ไม่ได้ตั้งค่าหรือเปลี่ยนแปลงมูลค่าของ $ a (มันแค่คืนค่า) ??$a ?? 'fallback'
Doin

2

มันดูเหมือนว่ามีข้อดีและข้อเสียของการใช้อย่างใดอย่างหนึ่งหรือ?? ?:โปรที่จะใช้?:คือการประเมินค่าเท็จและค่า null และ "" เหมือนกัน คอนดิชั่นคือมันรายงาน E_NOTICE ถ้าอาร์กิวเมนต์ก่อนหน้านี้เป็นโมฆะ ด้วย??โปรคือไม่มี E_NOTICE แต่ข้อผิดพลาดคือมันไม่ได้ประเมินค่า false และ null เหมือนกัน จากประสบการณ์ของฉันฉันเห็นผู้คนเริ่มใช้ null และ false interchangeably แต่ในที่สุดพวกเขาก็หันไปแก้ไขรหัสของพวกเขาให้สอดคล้องกับการใช้ null หรือ false แต่ไม่ใช่ทั้งคู่ ทางเลือกคือการสร้างเงื่อนไขที่ประกอบไปด้วยรายละเอียดเพิ่มเติม: (isset($something) or !$something) ? $something : $something_else.

ต่อไปนี้เป็นตัวอย่างของความแตกต่างของการใช้??โอเปอเรเตอร์โดยใช้ทั้ง null และ false:

$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---

$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---

อย่างไรก็ตามการอธิบายอย่างละเอียดเกี่ยวกับผู้ประกอบการที่ประกอบไปด้วยเราสามารถทำให้สตริงที่เป็นเท็จหรือว่างเปล่าได้ "" ราวกับว่ามันเป็นโมฆะโดยไม่ต้องขว้าง e_notice:

$false = null;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = false;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = "";
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = true;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: 1---

โดยส่วนตัวฉันคิดว่ามันจะดีจริงๆถ้าการปรับปรุง PHP ในอนาคตมีผู้ให้บริการรายใหม่อีกราย: :?แทนที่ไวยากรณ์ข้างต้น เช่น: // $var = $false :? "true";ไวยากรณ์นั้นจะประเมินค่า null, false และ "" เท่ากันและไม่ส่ง E_NOTICE ...


3
คุณสามารถใช้ $ var = $ false ?? null?: "สตริงว่างเปล่า / false / null / undefined";
RedSparr0w

โอ้โห ... ?? null ?:มันเยี่ยมมากเลยขอบคุณ คนฉลาด
Blaine Lafreniere

1
class a
{
    public $a = 'aaa';
}

$a = new a();

echo $a->a;  // Writes 'aaa'
echo $a->b;  // Notice: Undefined property: a::$b

echo $a->a ?? '$a->a does not exists';  // Writes 'aaa'

// Does not throw an error although $a->b does not exist.
echo $a->b ?? '$a->b does not exist.';  // Writes $a->b does not exist.

// Does not throw an error although $a->b and also $a->b->c does not exist.
echo $a->b->c ?? '$a->b->c does not exist.';  // Writes $a->b->c does not exist.

0

Null Coalescing operatorดำเนินการเพียงสองงาน: การตรวจสอบมันและwhether the variable is set whether it is nullดูตัวอย่างต่อไปนี้:

<?php
# case 1:
$greeting = 'Hola';
echo $greeting ?? 'Hi There'; # outputs: 'Hola'

# case 2:
$greeting = null;
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'

# case 3:
unset($greeting);
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'

ตัวอย่างรหัสข้างต้นระบุว่าNull Coalescing operatorปฏิบัติกับตัวแปรที่ไม่มีอยู่และตัวแปรที่ตั้งค่าNULLเป็นแบบเดียวกัน

Null Coalescing operatorternary operatorคือการปรับปรุงมากกว่า ดูตัวอย่างโค้ดต่อไปนี้เปรียบเทียบทั้งสอง:

<?php /* example: checking for the $_POST field that goes by the name of 'fullname'*/
# in ternary operator
echo "Welcome ", (isset($_POST['fullname']) && !is_null($_POST['fullname']) ? $_POST['fullname'] : 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
# in null coalecing operator
echo "Welcome ", ($_POST['fullname'] ?? 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.

ดังนั้นความแตกต่างระหว่างทั้งสองคือการที่ผู้ประกอบการได้รับการออกแบบมาเพื่อจัดการกับตัวแปรที่ไม่ได้กำหนดดีกว่าNull Coalescing operator ternary operatorขณะที่เป็นชวเลขternary operatorif-else

Null Coalescing operatorไม่ได้หมายถึงการแทนที่ternary operatorแต่ในบางกรณีการใช้งานเช่นในตัวอย่างด้านบนจะช่วยให้คุณสามารถเขียนโค้ดสะอาดได้โดยไม่ยุ่งยาก

เครดิต: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples


isset($_POST['fullname'])ตรวจสอบNULLค่าแล้ว - ดังนั้น&& !is_null($_POST['fullname'])ในตัวอย่างแรกนั้นซ้ำซ้อนอยู่แล้ว
Yaron U.

0

เมื่อใช้ superglobals เช่น $ _GET หรือ $ _REQUEST คุณควรระวังว่ามันอาจเป็นสตริงว่าง ในกรณีพิเศษนี้ตัวอย่างนี้

$username = $_GET['user'] ?? 'nobody';

จะล้มเหลวเนื่องจากค่าของ $ username ตอนนี้เป็นสตริงว่าง

ดังนั้นเมื่อใช้ $ _GET หรือแม้แต่ $ _REQUEST คุณควรใช้โอเปอร์เรเตอร์แทนเนอร์แทนเช่นนี้:

$username = (!empty($_GET['user'])?$_GET['user']:'nobody';

ตอนนี้ค่าของชื่อผู้ใช้ $ คือ 'ไม่มีใคร' ตามที่คาดไว้


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