Care este diferența dintre „??” și „?:” în PHP?

Mai jos, vom compara și analiza cei doi operatori condiționali, înlocuitorii și/sau scurtaturile if-lui, operatorul de scurtătură ternar (care ia 3 argumente), adică operatorul evlis „?:” și operatorul null-coalesciator „??„.

?: ( Operatorul Elvis)

Începând cu PHP 5.3+, putem folosi sintaxa operatorului condițional ternar scurt, eliminând partea din mijloc a operatorului ternar, pentru o evaluare mai rapidă:

expr1 ?: expr2;

Această sintaxă scurtă mai este numită operator elvis (?:). Următoarele afirmații sunt echivalente:

// elvis operator
expr1 ?: expr2;

// operatorul ternar
expr1 ? expr1 : expr2;

// bucla if/else
if (expr1) {
    return expr1;
} else {
    return expr2;
}

Părțile de mai sus se traduc în: dacă expr1 se evaluează ca fiind adevărată, returnează expr1, altfel returnează expr2.

Dacă se întâlnește o valoare falsă, operatorul evlis va returna cel de-al doilea operand. Sau, dacă se întâlnește o valoare adevărată, se returnează primul operand (adică valoarea adevărată). Rețineți, însă, că atunci când partea stângă a operatorului elvis se evaluează ca fiind adevărată, partea dreaptă a expresiei nu este evaluată. Acest lucru se datorează scurtaturii, ceea ce înseamnă că al doilea operand este executat sau evaluat doar dacă primul operand nu se evaluează ca fiind adevărat.

Este important să rețineți că valorile următoare sunt considerate false în PHP:

  • boolean false;
  • integer 0;
  • Float 0.0;
  • String „0”, sau ‘0’;
  • Un șir gol (adică ” sau „”);
  • Un tablou gol (adică [] sau array());
  • nul;
  • Obiectele SimpleXML create din tag-uri goale.

Rețineți că șirurile „00“, „0.0“, „\ 0“, și „fals“, toate sunt evaluate ca fiind true (adevărat) care sunt diferite de string-ul „0“ sau de booleanul false.

Lanțul Ternar:

Ternarele pot fi înlănțuite (adică returnează prima valoare adevărată pe care o întâlnește), de exemplu:

echo 0 ?: 1 ?: 2 ?: 3; // output: 1
echo 0 ?: false ?: [] ?: 'a'; // output: a

Aceasta este aceeași cu scrierea unei serii de declarații if / elseif / else, de exemplu:

if (expr1) {
    return expr1;
} else if(expr2) {
    return expr2;
} else if(expr3) {
    return expr3;
} else {
    return expr4;
}

?? (Operatorul null-coalesciator)

Începând cu PHP 7, a fost introdus operatorul null-coalesciator (??) care are următoarea sintaxă, asemănătoare cu a operatorului elvis:

expr1 ?? expr2;

Ceea ce înseamnă că expr1 este returnata atunci când expr1 există și NU este null; altfel se întoarce expr2. Aceasta este echivalentă cu următoarea:

// bucla if:
if (isset($x)) {
    return $x;
} else {
    return $y;
}

// sau, operatorul ternar:
return (isset($x) ? $x : $y);

// aceeași sintaxă cu operatorul null-coalescitor:
return $x ?? $y;

Pentru null-coalesciator, singurul lucru care contează este faptul că variabila există și nu este nulă, astfel încât, chiar și valorile false pot trece condiția.

Lanțul coalesciator

Ca și operatorul elvis, operatorul null-coalesciator poate fi înlănțuit (adică returnează prima valoare definită pe care o întâlnește), de exemplu:

$a ?? $b ?? $c ?? 'empty variables'; // output: 'empty variables'

În cazul în care nu există o valoare definită în lanțul de coalescență, va fi afișat un mesaj de eroare „Notice: Undefined variable: …”.

?: Vs. ??

Tabelul de mai jos arată o comparație a celor doi operatori cu o expresie dată:

Expression echo ($x ?: ‘hello’) echo ($x ?? ‘hello’)
$x = „”; ‘hello’ „”
$x = null; ‘hello’ ‘hello’
$x; ‘hello’
(and Notice: Undefined variable: x)
‘hello’
$x = []; ‘hello’ []
$x = [‘a’, ‘b’]; [‘a’, ‘b’] [‘a’, ‘b’]
$x = false; ‘hello’ false
$x = true; true true
$x = 1; 1 1
$x = 0; ‘hello’ 0
$x = -1; -1 -1
$x = ‘1’; ‘1’ ‘1’
$x = ‘0’; ‘hello’ ‘0’
$x = ‘-1’; ‘-1’ ‘-1’
$x = ‘random’; ‘random’ ‘random’
$x = new stdClass; object(stdClass) object(stdClass)

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>