Am avut de curând un duel aproape medieval pe o temă situată undeva la granița filozofiei aplicate. Pe scurt, mi-am luat o clanță consistentă pentru o linie de cod fiindcă, citez într-o traducere aproximativă din logudureză: cineva cu experiența ta n-ar trebui să greșească atât de jenant încât să nu-și verifice existența datelor de intrare, putând produce drept urmare mesaje de avertizare.

Foto: Bogdan Stoica
Este vorba de un proiect scris în PHP, iar linia vătămătoare (de fapt liniile, mă rog) prelua un parametru din variabila super-globală $_POST și apoi spune altor entități ce poate face cu dânsul:
$pillarName = $_POST['pillar_name'] ?? '';
În apărarea interlocutorului meu, este foarte ușor să cazi pradă unei confuzii, căci PHP este nimic dacă nu un limbaj de lumini și umbre. Având încă niște pâine de mâncat, m-am abținut să-i răspund fățiș cu aceleași accente stilistice, transmițându-i în schimb voalat prin intermediul unei expuneri comparative precum cea de mai jos.
După cum ziceam, este ușor să cazi, pradă confuziei, întrucât, într-adevăr, accesarea unei chei inexisente într-un vector (ori accesarea unei variabile cu totul nedefinite) produce o avertizare, mai precis o notificare de genul:
PHP Warning: Undefined variable $undefinedVarB in operator-showdown.php on line 15
Excepțiile sunt apelarea isset, apelarea empty și, din PHP 7.0, utilizarea operatorului de coalescență nulă – ?? – deci cel amintit în introducere. El este intim echivalent în realitate cu vechea modalitate bazată pe isset:
$pillarName = isset($_POST['pillar_name'])
? $_POST['pillar_name']
: '';
Iar acum ajungem la partea unde confuzia este justificabilă. Pe lângă operatorul de coalescență nulă mai există și operatorul Elvis – ?:. Denumirea sa are drept origini un fapt la fel de stupid precum vă imaginați: răsturnat cu 90 de grade în sensul acelor de ceasornic seamănă cu celebrul zbârnel al lui Elvis. Dacă tot au mers pe calea asta, aș fi preferat să denumească ?? operatorul Dublu-Elvis. Mulțumesc, mulțumesc, sunt aici în direct toată săptămâna.
Așteptarea, judecând exclusiv după forma similară cu operatorul Dublu-Elvis, este că nici utilizarea acestuia nu va emite vreo avertizare dacă este invocată asupra unei variabile nedefinite ori asupra unei chei inexistente dintr-un vector. Ori, vice-versa, dacă ai făcut de-a-ndoaselea cunoștință cu cei doi băieți răi.
Dezamăgirea va fi, din păcate, pe măsură. Operatorul Elvis este de fapt o simplă formă contrasă a operatorului ternar ordinar. Deci $pillarName = $_POST['pillar_name'] ?: ''; este pur și simplu echivalent cu:
$pillarName = $_POST['pillar_name'] ? $_POST['pillar_name'] : '';
Și, având în vedere că poți cădea pradă confuziei într-un sens, poți s-o cacarisești și-n celălalt sens și bănuiesc că asta s-a-tâmplat și-aci. Dans tous les cas, iată întreaga situație sumarizată-ntr-un table, cu adnotarea că mă bucur să văd că PHP nu și-a pierdut simțul umorului (vis-à-vis de șirul de caractere ‘0’):
$var | ?? 'fallback' | ?: 'fallback' | Observații |
|---|---|---|---|
unset | 'fallback' | ⚠️ Avertizare + 'fallback' | ?? nu generează avertizări, ?: generează avertizări |
null | 'fallback' | 'fallback' | Ambele produc valoarea 'fallback' |
'' (șir gol) | '' | 'fallback' | ?? returnează șirul gol, ?: o evaluează ca valoare de adevăr false |
0 (int zero) | 0 | 'fallback' | ?? păstrează valoarea int 0, ?: o evaluează ca valoare de adevăr false |
'0' (string) | '0' | 'fallback' | ?? păstrează valoarea '0', ?: o evaluează ca valoare de adevăr false |
false | false | 'fallback' | ?? păstrează valoarea false, ?: returnează 'fallback' |
true | true | true | Ambele returnează true |
'hello' | 'hello' | 'hello' | Ambele returnează false |
array() gol | array() gol | 'fallback' | ?? returnează vectorul gol, ?: o evaluează ca valoare de adevăr false |