2009-09-17 17 views
40

che stiamo cercando di implementare nuove linee guida dello stile di codifica per la nostra squadra, il codesniffer PHP è la stampa di un allarme su casi di istruzioni switch quando non "rompere" si trova come:Gli stili di codifica PHP vengono restituiti; in switch/case

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

c'è qualche buoni motivi per usare:

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

?? la pausa non viene mai raggiunta?

+0

Suggerirei di fare della domanda @categoria una domanda a parte, poiché non è correlata. –

+0

Forse codesniffer è solo sbagliato e non controlla 'return' ma solo per' break'. – Gumbo

risposta

65

E 'perfettamente valido per lasciare fuori il break quando si return da un switch.

Tuttavia, è pratica comune aggiungere break s ad ogni case come pratica defensive programming.

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

    case 2: 
     return 2; 
     break; 
} 

L'idea è che dovrebbe in seguito cambiare il codice in case 1 e rimuovere l'istruzione di ritorno, si potrebbe dimenticare di aggiungere un break.

Ciò causerebbe accidentalmente la caduta del flusso del programma a case 2.

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

    case 2: 
     return 2; 
     break; 
} 

caduta attraverso dichiarazioni caso è un po 'insolito e si dovrebbe aggiungere un commento al codice quando lo si fa a dimostrare che è intenzionale.

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

    case 2: 
     return 2; 
     break; 
} 

Come per molte pratiche di programmazione difensiva hai avuto modo di equilibrare se il codice bloat - che potenzialmente ingombra il codice e renderlo meno leggibile - vale la pena o no.

+0

_ "se in seguito dovessi cambiare il tuo codice nel caso 1" _ allora dovresti cambiare tutto il codice come richiesto e testarlo. Il codice dovrebbe essere leggibile, esplicito e chiaro, per rendere semplici le modifiche future. Ma in qualcosa di semplice come le dichiarazioni di switch è un modo OTT di inserire clausole anti-Gotcha come questa. Può forse rendere l'intenzione meno chiara. "Una pausa ?? ma c'è un ritorno ??" _ "se in seguito dovessi cambiare il tuo codice nel caso 1 e rimuovere la dichiarazione di ritorno, potresti dimenticarti di aggiungere un'interruzione" _ allora probabilmente dovresti avere una lunga interruzione da parte, dato che hai un caso con niente in esso ... – James

-11

Dal manuale di PHP (http://us3.php.net/manual/en/control-structures.switch.php):

PHP continua l'esecuzione delle istruzioni fino alla fine del blocco switch o la prima volta che vede un'istruzione break. Se non si scrive una dichiarazione di interruzione alla fine dell'elenco di istruzioni di un caso, PHP continuerà a eseguire le dichiarazioni del caso seguente. Ad esempio:

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

Qui, se $ i è uguale a 0, PHP eseguirà tutte le istruzioni di eco! Se $ i è uguale a 1, PHP eseguirà le ultime due istruzioni di eco. Si otterrebbe il comportamento previsto ('i pari a 2' verrebbero visualizzati) solo se $ i è uguale a 2. Pertanto, è importante non dimenticare le istruzioni di interruzione (anche se si consiglia di evitare di fornirle di proposito in determinate circostanze).

+3

Ma sta parlando di ritorno da un interruttore, non stai rispondendo alla sua domanda –

+0

Non rilevante in questo caso. Il blocco 'case' viene chiuso da' return'. – Gumbo

+2

Hai ragione - non ho letto correttamente la domanda. mi spiace per quello – Sander

-1

io non sono un esperto in perfetta codifica ma penso che il validatore preferirebbe qualcosa di simile

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

} 
return $ret 

Penso che utilizzando il ritorno nel caso in cui dichiarazione di spezzare il flusso del codice non è in realtà una pratica migliore. Ecco, questo è il motivo per cui il validatore dire che non c'è nessuna rottura ...

Per le tue domande su a categoria, non lo so ... mi dispiace

+0

... forse non è la preferenza di @ là perché consuma attribuzioni "non richieste" ... Ma è una buona scelta quando il '$ ret' esiste già (è richiesto) per fare qualcosa nell'algoritmo. –

3

Ho una soluzione molto migliore.Si prega di seguire il codice sottostante per sopra statment interruttore:

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

Non si verificherà alcun errore e il codice è adatto anche per i concetti.

1

Se il tuo "php codesniffer sta stampando un avviso" prova a ottenere un altro codice migliore e non dimenticare di provare a utilizzare l'ultima versione stabile di PHP. È possibile, naturalmente, scrivere uno break dopo uno return, ma non ha senso, perché non verrà mai letto affatto. Il tuo codice è OK

Guardate questa:

$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" 

A mio parere questo è più semplice e meglio: meno linee => meno codice per mantenere :-)

0

Per rispondere alla tua domanda, non c'è nessuna buona ragione per avere qualcosa che non fa nulla Pensaci in questo modo, un commento dopo lo return invece di un break dicendo "non dimenticare" avrà lo stesso effetto - nessuno. E così sembra sciocco, giusto?

A meno che non sia necessario impostare una var per utilizzarla in un secondo momento, suggerirei che l'approccio che hai è perfetto. Conoscevo l'intento del codice entro 2 secondi dal guardarlo. Avere un break crea solo confusione.

Non esiste una taglia adatta a tutti. L'approccio corretto dipende da quello che si adatta allo scenario. Impostare una variabile in ogni case e avere un break potrebbe essere la strada giusta, o forse solo il ritorno ha un senso.

 
 


Alcune osservazioni su altri suggerimenti formulati nelle risposte:

1)Non avendo un break dopo return significa potrebbero sorgere problemi se il codice viene poi cambiato

Wh sempre possibile, il codice dovrebbe essere esplicito, oltre che leggibile e chiaro. Possiamo anche codificare in un modo per rendere più facili le modifiche future. Ma in qualcosa di semplice come un switch non dovrebbe esserci alcun problema e non è necessario disporre di una rete di sicurezza per refactoring un case in seguito per aggiungere o rimuovere un return o break.

In effetti, se è stato rimosso un return e "non hai notato non c'era break" allora questo è un povero errore e potrebbe essere fatto in qualsiasi parte del codice. Nessun controllo Gotcha ti salverà da questo. E si dovrebbe fare una codifica molto attenta per i potenziali futuri, poiché quel potenziale potrebbe non accadere mai, o potrebbe accadere qualcos'altro, e si finisce per mantenere il codice obsoleto per anni.

Nella stessa ottica, questa è stata considerata una rete di sicurezza per le modifiche future. Che cosa succede se si rimuove lo return e si è lasciato accidentalmente nella rete di sicurezza break quando è stato rimosso?

Anche se questa dichiarazione di commutazione fosse uno scenario di vita o di morte, codice veramente serio, sarei contrario ad aggiungere l'interruzione "inutile" dopo il ritorno.Assicurati solo che chiunque stia lavorando sul codice sapeva cosa stavano facendo, ed è stato riesaminato dal codice con abbastanza occhi e testato completamente.
Se fosse così grave, avresti controlli supplementari in posto meglio di una rete di sicurezza proposta per catturare gli sviluppatori sciatti.

Per sostenere che una pausa dopo il ritorno aggiunge una rete di sicurezza, significa che non si sta codificando o testando correttamente. Se si tratta di una rete di sicurezza ritenuta utile, è probabile che ci siano tonnellate di errori nel codice in luoghi potenzialmente più gravi.

L'articolo wiki di "Programmazione difensiva" è stato collegato a, ma non è qui rilevante:

programmazione difensiva è una forma di disegno difensivo destinato a garantire la funzione continua di un pezzo di software sotto imprevista circostanze.

Lasciando una rete di sicurezza break in non è uno scenario di circostanze impreviste, né programmazione difensiva. È solo una cattiva programmazione, e non è possibile sporcare il codice con il codice di backup nel caso in cui non si codifichi correttamente quando si modifica qualcosa. È un approccio così brutto alla codifica. L'argomento che "se qualcuno ha rimosso il reso non funzionerà", beh potresti anche avere un errore di battitura nel caso var, o dimenticare di scrivere il caso, o ...

I ritorni return, e tu don ' t codice "difensivo" per evitare un ritorno fallito. Ciò significherebbe che PHP è rotto e non dovrai riempire il tuo codice con le reti di sicurezza per far fronte a questo. È qualcosa che hai su un livello molto più alto.

2)break dopo return mantiene esplicita

Ma è esplicitamente sbagliato. Il return restituisce, quindi l'interruzione non avverrà. Per me è tempo di graffiare la testa chiedendomi se ho perso l'intento - non per molto tempo visto che è chiaro cosa succederà , ma ci sarà un momento in cui ci rifletterò per assicurarmi di non aver perso qualcosa.

Anche se non è valida o errore di avere un return e poi break nello stesso case, è solo del tutto inutile in quanto il break non fa nulla. È un codice inutile che deve essere visto, mantenuto e capito perché non è logico.

Se esplicito è l'obiettivo principale e avere un break dopo una return urks voi, perché è inutile, allora direi che sarebbe meglio per impostare una variabile e break, per poi tornare la variabile dopo la rottura dall'interruttore.
Come @RageZ risposta https://stackoverflow.com/a/1437476/2632129

 

3)impostare una variabile e tornare dopo l'istruzione switch è completato

Non c'è niente di sbagliato in questo approccio a tutti, ma se non c'è motivo per memorizzare il valore in una variabile (uso successivo, ecc.) quindi è bene tornare immediatamente quando non c'è bisogno di fermarsi a fare qualsiasi altra cosa.

Ciò mostra un chiaro intento: restituire un valore non appena il caso è abbinato.

Problemi correlati