2009-09-17 14 views
40

staramy się realizować nowe wytyczne styl kodowania dla naszego zespołu, codesniffer php drukuje ostrzeżenie włącznik przypadku sprawozdania kiedy nie „break” znajduje się następująco:Powracają style kodowania PHP; w przypadku przełącznika/

switch ($foo) { 
    case 1: 
     return 1; 
    case 2: 
     return 2; 
    default: 
     return 3; 
} 

jest jakiś dobry powód do użycia:

switch ($foo) { 
     case 1: 
     return 1; 
     break; 
    } 

?? przerwa nigdy nie jest osiągnięta?

+0

Proponuję, aby pytanie @kategorii było osobnym pytaniem, ponieważ nie ma to związku. –

+0

Może codesniffer jest po prostu niepoprawny i nie sprawdza 'return', ale tylko dla' break'. – Gumbo

Odpowiedz

65

Jest idealnie ważne, aby pominąć break kiedy return przechodząc z switch.

Ale dość powszechną praktyką jest dodawanie jawnych break s do każdego case jako praktyki defensive programming.

switch ($foo) { 
    case 1: 
     return 1; 
     break; 

    case 2: 
     return 2; 
     break; 
} 

Chodzi o to, że należy później zmienić swój kod w case 1 i usunąć komunikatu zwrotnego, można zapomnieć dodać break.

To by przypadkowo spowodowało, że przepływ programu spadnie do case 2.

switch ($foo) { 
    case 1: 
     somethingDifferent(); 

    case 2: 
     return 2; 
     break; 
} 

Falling poprzez oświadczenia sprawa jest nieco nietypowa i należy dodać komentarz do kodu, kiedy robisz to, aby pokazać, że jest to zamierzone.

switch ($foo) { 
    case 1: 
     somethingDifferentAndWeWantToDoCase2AsWell(); 
     // fallthrough 

    case 2: 
     return 2; 
     break; 
} 

Jak wiele obronnych praktyk programowania masz do równowagi czy wzdęć kodu - co potencjalnie zaśmiecanie kodu i uczynić go mniej czytelny - warto czy nie.

+0

_ "jeśli później zmienisz kod w przypadku 1" _, powinieneś zmienić cały kod zgodnie z wymaganiami i przetestować go. Kod powinien być czytelny, jednoznaczny i jasny, aby przyszłe zmiany były proste. Ale w tak prostym, jak instrukcje przełączania, sposób OTT umieszcza takie klauzule. Może to spowodować, że intencja będzie mniej jasna. "Przerwa ??, ale jest powrót?" _ "jeśli później zmienisz kod w przypadku 1 i usuniesz oświadczenie zwrotne, możesz zapomnieć o dodaniu przerwy" _ wtedy powinieneś mieć dłuższą przerwę od dzielenia, ponieważ wtedy masz skrzynkę z niczym nie zawartą ... – James

-11

z podręcznika PHP (http://us3.php.net/manual/en/control-structures.switch.php):

PHP kontynuuje wykonywanie sprawozdań do końca bloku przełącznika, lub po raz pierwszy widzi instrukcji break. Jeśli nie napiszesz instrukcji break na końcu listy instrukcji, PHP będzie kontynuowało wykonywanie instrukcji następującej sprawy. Na przykład:

<?php 
switch ($i) { 
    case 0: 
     echo "i equals 0"; 
    case 1: 
     echo "i equals 1"; 
    case 2: 
     echo "i equals 2"; 
} 
?> 

Tutaj, jeśli $ i jest równe 0, PHP wykona wszystkie instrukcje echa! Jeśli $ i jest równe 1, PHP wykona ostatnie dwa instrukcje echa. Otrzymasz oczekiwane zachowanie ("i równa się 2" zostanie wyświetlona) tylko wtedy, gdy $ i jest równe 2. Dlatego ważne jest, aby nie zapominać o stwierdzeniach przerwy (nawet jeśli możesz chcieć uniknąć dostarczania ich celowo w pewnych okolicznościach).

+3

Ale on mówi o powrocie z przełącznika, nie odpowiadasz na jego pytanie –

+0

Nie dotyczy w tym przypadku. Blok 'case' jest zamykany przez' return'. – Gumbo

+2

Masz rację - nie przeczytałem poprawnie tego pytania. przepraszam za to – Sander

-1

Nie jestem ekspertem w doskonałej kodowania ale myślę, że walidator woleliby coś takiego

switch ($foo) { 
    case 1: 
     $ret = 1; 
     break; 
    case 2: 
     $ret = 2; 
     break; 
    default: 
     $ret = 3 

} 
return $ret 

myślę, używając zwrotu w instrukcji case przerwać przepływ kodu naprawdę nie jest najlepszym rozwiązaniem. Więc dlatego walidator powiedzieć, nie ma przerwy ...

za pytanie w kategorii, nie wiem ... przepraszam

+0

... być może nie jest to preferencja @ therefromhere, ponieważ zużywa "nie wymagane" atrybucje ... Ale jest dobrym wyborem, gdy '$ ret' już istnieje (jest wymagane), aby zrobić coś w algorytmie. –

3

Mam znacznie lepsze rozwiązanie.Proszę postępować zgodnie z poniższym kodem dla powyższej instrukcji przełącznika:

$result = 3; // for default case 
switch ($foo) { 
    case 1: 
     $result = 1; 
     break; 
    case 2: 
     $result = 2; 
     break;  
    default: 
     // do nothing 
} 
return $result; 

Nie spowoduje to żadnego błędu, a kod jest również zgodny z koncepcjami.

1

Jeśli twój "php codesniffer" drukuje ostrzeżenie "spróbuj uzyskać jeszcze lepsze kodyniffer i nie zapomnij spróbować użyć ostatniej stabilnej wersji PHP. Możesz oczywiście napisać break po return, ale to nie ma sensu, ponieważ nigdy nie będzie czytane w ogóle. Twój kod jest OK.

Spójrz na to:

$fn = function($ar) { 
    switch ($ar) { 
     case 1: 
      return "uno"; 
     case 2: 
      return "two"; 
     default: 
      return "mehr als zwei"; 
    } 
}; 
$str = $fn(4); // return "mehr als zwei" 

Moim zdaniem jest to prostsze i lepsze: mniej linii => mniej kodu do utrzymania :-)

0

Aby odpowiedzieć na to pytanie, nie istnieje żaden powód do mieć coś, co nie robi nic. Pomyśl o tym w ten sposób, komentarz po return zamiast break powiedzenie "nie zapomnij" będzie miało ten sam wpływ - brak. I tak to brzmi głupio, prawda?

Jeśli nie musisz ustawić var, aby użyć go później, chciałbym zasugerować, że podejście, które masz, jest całkowicie w porządku. Znałem intencje kodu w ciągu 2 sekund od patrzenia na to. Posiadanie break tylko wprowadza zamieszanie.

Nie ma jednego uniwersalnego rozmiaru. Prawidłowe podejście zależy od tego, który z nich pasuje do scenariusza. Ustaw zmienną w każdym case, a posiadanie break może być właściwą drogą, a może tylko powrót ma sens.

 
 


Niektóre obserwacje na inne sugestie w odpowiedzi:

1)nie mając break po return oznacza problemy mogą powstać, jeśli kod jest później zmienił

Wh możliwe, kod powinien być wyraźny, a także czytelny i czytelny. Możemy również kodować w taki sposób, aby ułatwić przyszłe zmiany. Ale w czymś tak prostym, jak switch, nie powinno to stanowić problemu i nie potrzeba żadnej siatki bezpieczeństwa do późniejszej zmiany case, aby dodać lub usunąć return lub break.

W rzeczywistości, jeśli wyjął return i „nie zauważył nie było break” to jest to biedny błędem i może być wykonane w dowolnej części kodowania. Żadne sprawdzanie cię nie uratuje. I trzeba bardzo ostrożnie kodować przyszłe potencjały, ponieważ ten potencjał może nigdy nie nastąpić, albo coś innego może się wydarzyć, a ty po prostu skończysz utrzymywać przestarzały kod przez lata.

W tym samym duchu argumentowano, że jest to sieć bezpieczeństwa dla przyszłych zmian - Co się stanie, jeśli usuniesz return i przypadkowo pozostawiłeś w tej sieci bezpieczeństwa break, kiedy powinieneś ją usunąć?

Nawet jeśli ta zmiana byłaby scenariuszem życia lub śmierci, naprawdę poważnym kodem, byłbym przeciwny dodaniu "bezsensownej" przerwy po powrocie.Upewnij się tylko, że ktokolwiek pracował nad kodem, wiedział, co robią, i został sprawdzony pod kątem wystarczającej liczby oczu i przetestowany w pełni.
Jeśli byłaby to poważna sprawa, lepiej byłoby przeprowadzić dodatkowe kontrole niż proponowana sieć bezpieczeństwa, aby złapać niechlujstwa.

Argument, że przerwa po powrocie dodaje siatkę bezpieczeństwa, oznacza, że ​​nie kodujesz ani nie testujesz prawidłowo. Jeśli jest to sieć bezpieczeństwa uznana za użyteczną, prawdopodobnie istnieje mnóstwo błędów w kodzie w potencjalnie poważniejszych miejscach.

W artykule wiki z „Defensywny Programowanie” było związane, ale to nie jest istotne tutaj:

Defensive programowanie jest formą konstrukcji obronnej mające na celu zapewnienie ciągłą funkcję kawałek oprogramowania w nieprzewidzianych Okoliczności.

Pozostawienie siatki zabezpieczającej break nie jest scenariuszem nieprzewidzianych okoliczności ani programowaniem defensywnym. To po prostu złe kodowanie, , a nie możesz zaśmiecać kodu z kodem zapasowym, na wypadek gdybyś nie poprawił kodu, gdy zmienisz coś.. To złe podejście do kodowania. Argument, że "jeśli ktoś usunięty zwróci, to nie zadziała", możesz również mieć literówkę w przypadku var, lub zapomnieć o napisaniu sprawy, lub ...

return powraca, a ty nie t kod "defensywnie", aby uniknąć niepowodzenia powrotu. To by znaczyło, że PHP jest zepsute, a ty nie wypełnisz swojego kodu siatkami bezpieczeństwa, aby to zaspokoić. To coś, co masz na wyższym poziomie.

2)break po return utrzymuje ją wyraźne

Ale to wyraźnie źle. return powraca, więc przerwa nie nastąpi. Dla mnie to czas na głowę, zastanawiając się, czy nie przeoczyłem intencji - nie na długo, ponieważ jasne jest, co się stanie, ale będzie moment, w którym zastanowię się nad tym, by upewnić się, że czegoś nie przeoczyłem.

Chociaż to nie jest nieważny lub błąd mieć return a następnie break w tym samym case, to po prostu całkowicie bezcelowe, ponieważ break nic nie robi. Jest to bezcelowy kod, który musi być widoczny, utrzymywany i zorientowany, ponieważ nie jest logiczny.

Jeśli wyraźny jest celem rdzeń i posiadające break po return urks ty, bo to bez sensu, to powiedziałbym, że byłoby lepiej, aby ustawić zmienną i break, a następnie powrócić zmiennej po zerwaniu z przełącznika.
Jak @RageZ odpowiedź https://stackoverflow.com/a/1437476/2632129

 

3)Ustaw zmienną i powrót po Instrukcja switch jest zakończona

Nie ma nic złego z tym podejściem w ogóle, ale jeśli nie ma powód do przechowywania wartości w zmiennej (później użycie itp.), to dobrze jest powrócić natychmiast, gdy nie ma potrzeby, aby się kręcić, aby zrobić cokolwiek innego.

To pokazuje wyraźne zamiary - zwróć wartość natychmiast po dopasowaniu sprawy.

Powiązane problemy