standard - Los estilos de codificación PHP vuelven; en interruptor/caja
psr 3 php (6)
Del manual de PHP ( http://us3.php.net/manual/en/control-structures.switch.php ):
PHP continúa ejecutando las instrucciones hasta el final del bloque de conmutadores, o la primera vez que ve una instrucción de interrupción. Si no escribe una declaración de interrupción al final de la lista de estados de cuenta de un caso, PHP continuará ejecutando las declaraciones del siguiente caso. Por ejemplo:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
Aquí, si $ i es igual a 0, ¡PHP ejecutaría todas las declaraciones de eco! Si $ i es igual a 1, PHP ejecutaría las dos últimas instrucciones de eco. Obtendría el comportamiento esperado (''i es igual a 2'' se mostraría) solo si $ i es igual a 2. Por lo tanto, es importante no olvidar las declaraciones de interrupción (aunque es posible que desee evitar el suministro a propósito en determinadas circunstancias) )
estamos tratando de implementar nuevas pautas de estilo de codificación para nuestro equipo; php codesniffer está imprimiendo una advertencia en las declaraciones de mayúsculas y minúsculas cuando no se encuentra un "corte" como:
switch ($foo) {
case 1:
return 1;
case 2:
return 2;
default:
return 3;
}
¿Hay alguna buena razón para usar:
switch ($foo) {
case 1:
return 1;
break;
}
?? el descanso nunca se alcanza?
Es perfectamente válido dejar afuera el break
cuando return
de un switch
.
Pero es una práctica bastante común agregar saltos explícitos a cada case
como una práctica de programación defensiva .
switch ($foo) {
case 1:
return 1;
break;
case 2:
return 2;
break;
}
La idea es que, si luego cambias tu código en el case 1
y eliminas la declaración de devolución, podrías olvidarte de agregar un break
.
Eso causaría accidentalmente que el flujo del programa cayera al case 2
.
switch ($foo) {
case 1:
somethingDifferent();
case 2:
return 2;
break;
}
Pasar por las declaraciones de casos es un poco inusual y debe agregar un comentario a su código cuando lo haga para demostrar que es intencional.
switch ($foo) {
case 1:
somethingDifferentAndWeWantToDoCase2AsWell();
// fallthrough
case 2:
return 2;
break;
}
Al igual que con muchas prácticas de programación defensivas, debe equilibrar si vale la pena o no, el engrosamiento del código, que potencialmente desordena su código y lo hace menos legible.
No soy un experto en codificación perfecta, pero creo que el validador preferiría algo así
switch ($foo) {
case 1:
$ret = 1;
break;
case 2:
$ret = 2;
break;
default:
$ret = 3
}
return $ret
Creo que usar return en el enunciado de caso para romper el flujo del código no es realmente una mejor práctica. Entonces, es por eso que el validador dice que no hay interrupción ...
Para su pregunta sobre la categoría, no sé ... lo siento
Para responder a su pregunta, no, no hay una buena razón para tener algo que no haga nada. Piénselo de esta manera, un comentario después de la return
lugar de un break
diciendo "no lo olvides" tendrá el mismo efecto: ninguno. Y ponlo así suena tonto, ¿verdad?
A menos que necesites configurar una var para usarla más adelante, te sugiero que el enfoque que tienes esté perfectamente bien. Conocí la intención del código en 2 segundos después de mirarlo. Tener un break
solo crea confusión.
No hay una talla única para todos. El enfoque correcto depende de lo que se ajuste al escenario. Establezca una variable en cada case
y tener un break
puede ser el camino correcto, o tal vez simplemente regresar tiene sentido.
Algunas observaciones sobre otras sugerencias hechas en las respuestas:
1) No tener un break
después del return
significa que podrían surgir problemas si el código se cambia posteriormente
Siempre que sea posible, el código debe ser explícito, legible y claro. También podemos codificar de una manera que facilite los cambios futuros. Pero en algo tan simple como un switch
no debería haber ningún problema y no necesita una red de seguridad para refactorizar un case
más adelante para agregar o eliminar una return
o un break
.
De hecho, si eliminó una return
y " no notó que no hubo un break
", ese es un error grave y podría hacerse en cualquier parte de la codificación. Ninguna comprobación gotcha te salvará de eso. Y uno debe tener una codificación muy cuidadosa para los potenciales futuros, ya que ese potencial nunca puede suceder, o puede pasar algo más, y usted acaba manteniendo un código obsoleto durante años.
En el mismo sentido, se argumentó que esto era una red de seguridad para futuros cambios: ¿qué pasaría si eliminara la return
y la dejara accidentalmente en esa break
red de seguridad cuando debería haberla quitado?
Incluso si esta declaración de cambio fuera un escenario de vida o muerte, un código realmente serio, me opondría a agregar el "inútil" descanso después de la devolución. Solo asegúrense de que quien esté trabajando en el código sepa lo que están haciendo, y fue revisado por varios ojos y probado completamente.
Si fuera tan serio, entonces tendría controles adicionales implementados mejor que una red de seguridad propuesta para atrapar a los desarrolladores descuidados.
Argumentar que romper después de regresar agrega una red de seguridad, significa que no está codificando o probando adecuadamente. Si se trata de una red de seguridad considerada útil, es probable que haya muchos errores en el código en lugares potencialmente más serios.
El artículo de la wiki de "Programación Defensiva" fue vinculado, pero no es relevante aquí:
La programación defensiva es una forma de diseño defensivo que pretende garantizar la función continua de un software en circunstancias imprevistas.
Dejar una break
en la red de seguridad no es un escenario de circunstancias imprevistas, ni programación defensiva. Es solo una mala codificación, y no se puede ensuciar tu código con un código de respaldo en caso de que no codifiques correctamente cuando cambies algo . Ese es un enfoque tan malo para la codificación. El argumento de que "si alguien eliminó el retorno, no funcionará", también podría tener un error tipográfico en el caso var, u olvidarse de escribir el caso, o ...
La return
vuelve, y no codifica "defensivamente" para evitar un error de devolución. Eso significaría que PHP está roto, y no va a llenar su código con redes de seguridad para atender a eso. Eso es algo que tienes en un nivel mucho más alto.
2) break
después del return
mantiene explícito
Pero está explícitamente mal. El return
vuelve, por lo que el descanso no sucederá. Para mí, eso es el momento más oportuno para preguntarme si me he perdido la intención, no por mucho tiempo, ya que está claro lo que sucederá, pero habrá un momento en el que reflexionaré para asegurarme de no haberme perdido algo.
Si bien no es inválido o un error tener una return
y luego break
en el mismo case
, es completamente inútil ya que el break
no hace nada. Es un código sin sentido que necesita ser visto, mantenido y resuelto, ya que no es lógico.
Si el objetivo principal es explícito y tener un break
después de un return
te incita porque no tiene sentido, entonces diría que sería mejor establecer una variable y break
, luego devolver la variable después de interrumpir el cambio.
Me gusta @RageZ answer https://.com/a/1437476/2632129
3) Establecer una variable y regresar después de que se complete la instrucción de cambio
No hay nada de malo en este enfoque, pero si no hay ninguna razón para almacenar el valor en una variable (uso posterior, etc.), entonces es bueno regresar inmediatamente cuando no haya necesidad de esperar para hacer otra cosa.
Eso muestra una intención clara: devuelve un valor tan pronto como coincida el caso.
Si su "php codesniffer está imprimiendo una advertencia", trate de obtener otro código mejor y no olvide intentar usar la última versión estable de PHP. Por supuesto, puede escribir un break
después de una return
, pero no tiene sentido, porque nunca se leerá. Tu código está bien.
Mira este:
$fn = function(int $ar): string{
switch ($ar) {
case 1:
return "uno";
case 2:
return "two";
default:
return "mehr als zwei";
}
};
$str = $fn(4); // return "mehr als zwei"
En mi opinión, esto es más simple y mejor: menos líneas => menos código para mantener :-)
Tengo una solución mucho mejor. Siga el siguiente código para la declaración del cambio anterior:
$result = 3; // for default case
switch ($foo) {
case 1:
$result = 1;
break;
case 2:
$result = 2;
break;
default:
// do nothing
}
return $result;
No dará lugar a ningún error y el código también está bien con los conceptos.