Używanie trójskładnikowego operatora PHP z tylko dwoma argumentami

9

Niedawno przeglądałem część mojego kodu i zauważyłem, że w przypływie roztargnienia pozostawiłem strukturę podobną do następującej:

$guid = empty($subscription->guid) ?  : $subscription->guid;

Teraz nie działało to tak, jak powinno i jest złe , ale ponieważ ta właściwość jest zawsze ustawiona teraz, działała dobrze i nie ma błędu składniowego od 5.3 z powodu następującej zmiany :

Od wersji PHP 5.3 można pominąć środkową część operatora trójskładnikowego. Wyrażenie wyrażenie1: wyrażenie 3 zwraca wyrażenie 1, jeśli wyrażenie 1 ma wartość PRAWDA, a wyrażenie 3 w przeciwnym razie.

Nie wiedziałem o tej zmianie, a teraz jestem ciekawy, czy powinienem jej użyć, czy nie. To jest coś, co było bardzo brakuje w językach takich jak rubin, gdzie można zrobić np a = b || cdostać albo bczy czamiast „prawdziwego” logiczną. Jednak składnia, którą wybrali dla operatora trójskładnikowego, wydaje mi się nieco sprzeczna z intuicją. Czy powinienem używać tego w kodzie produkcyjnym? Zdecydowanie rzuciłem się, gdy zobaczyłem to przez przypadek.

Matthew Scharley
źródło
Powinieneś użyć zerowego operatora koalescencyjnego dla tego Varsolp techflirt.com/null-coalescing-operator-php
Ankur Kumar Singh

Odpowiedzi:

7

Trójskładnikowy operator warunkowy bez drugiego argumentu jest nieco nowatorski, ale jest podobny do 1 operatora zerowego koalescencji występującego w innych językach pochodnych Algolu, takich jak C # i Perl, a jak wspominasz, ||operator w Ruby (i JavaScript).

Na początku wygląda to dziwnie, ale nie jest zbytnio na zewnątrz (zwłaszcza, że ​​w innych językach istnieje precedens dla podobnych operatorów) i może zaoszczędzić sporo naciśnięć klawiszy. A jeśli to, co stało się z ogranicznikiem przestrzeni nazw ( \), jest jakąkolwiek wskazówką, społeczność PHP ostatecznie przyjmie dziwne składnie.

Ale jednym z głównych problemów, z którymi zwykle spotykają się aplikacje PHP, jest (czasem) wyjątkowo długi czas opóźnienia między wydaniem nowej wersji PHP a momentem, gdy host zaczyna ją obsługiwać. Prowadzi to do problemów, w których musisz być kompatybilny wstecz ze starszymi wersjami PHP, rezygnując z korzystania z takich zmian wygody.

Jeśli to nie dotyczy Ciebie, a Twój zespół zgadza się na jego użycie (lub jeśli jesteś programistą solo, jeśli czujesz się z tym komfortowo), na pewno idź. Podobnie jak ogranicznik przestrzeni nazw, naprawdę myślę, że naprawdę będzie to kwestia tego, kiedy, a nie, czy będzie to akceptowalne we wszystkich przyszłych projektach PHP.


Uwaga 1 : Ale nie identyczne, biorąc pod uwagę, że operatory zerowo-koalescencyjne testują tylko wartości inne niż zerowe (i nie prawdziwe wartości, takie jak PHP), a ?:składnia nie tłumi niezdefiniowanych powiadomień, jak wspomniano w komentarzach .

Społeczność
źródło
W tej chwili mój „zespół” składa się wyłącznie ze mnie. Hosting nie stanowi problemu, ponieważ zazwyczaj hostujemy 98% witryn, które tworzymy, a oprócz tego 5.3.6. Zdaję sobie sprawę, że sama funkcjonalność nie jest tak niezwykła, tylko jej składnia, która była rdzeniem mojego pytania. Istnieje również problem polegający na tym, że nie działa on jak operator koalescencji zerowej bez dodatkowej składni ( @aby ukryć powiadomienia o niezdefiniowanych rzeczach).
Matthew Scharley
3
@MatthewScharley Jeśli awaria separatora przestrzeni nazw (\) jest jakąkolwiek wskazówką, dziwna składnia nie stanowi bariery dla powszechnego przyjęcia w PHP. To naprawdę sprowadza się do tego, kiedy, a nie, czy powinieneś zacząć go używać.
3

Dla mnie wygląda to na błąd w kodzie. Wygląda to źle i ogólnie rzecz biorąc, unikam używania składni, która wygląda na to, że popełniłeś błąd w celu zaoszczędzenia kilku naciśnięć klawiszy. Kiedy ty (lub ktoś inny) wróci później, aby przeczytać kod później, myślę, że ten wiersz cię zaskoczy i sprawi, że będziesz musiał poświęcić czas na analizowanie tego, co robi, co jest w zasadzie prostą operacją.

MattBelanger
źródło
Podany przykład jest zły . Prawidłowe użycie funkcji zgodnie z przeznaczeniem byłoby $foo = @$bar ?: 'baz'równoważne $foo = (@$bar ? $bar : 'baz'). Zgadzam się jednak z twoimi komentarzami.
Matthew Scharley,
1

Cóż, PHP ma typ boolowski, a ||operator zwraca boolen, więc w PHP wynikiem $a || $bjest boolean, jest to spójne z, &&ponieważ &&nie ma sensu zwracać jednego lub drugiego, ale ma sens zwracanie true/ false. To, że wszystkie operatory logiczne zwracają boole, również wydaje się dość logiczne.

Dodatkowo nie jest to wynalazek z PHP, ale po C, z którego pochodzi wiele elementów projektu „klasycznego” PHP. Cytując z §6.5.14 normy C99:

|| operator daje 1, jeżeli którykolwiek z jego argumentów jest różny od 0; w przeciwnym razie daje 0. Wynik ma typ int.

I, cóż, do czego powinieneś użyć?: Czy nie można na nie odpowiedzieć w formie ogólnej, ale pamiętaj: Najlepszym sposobem na język jest użycie dostarczonych przez niego konstrukcji i wykorzystanie sugerowanych przez niego paradygmatów. Pisanie kodu Java takiego jak kod C lub odwrotnie nie ma sensu ;-)

Johnnes
źródło
0

Myślę, że jest to bardzo przydatny operator i zdecydowanie powinien zostać użyty, ponieważ standard językowy go wyraźnie definiuje.

Zauważ, że oficjalnie nazywa się to Elvis Operator w Grooy (dlaczego? Po prostu przyjrzyj się temu uważnie!) I zaproponowano wprowadzenie go w Javie 7.

Michael Borgwardt
źródło