statement psr2 psr programacion estándares estandares estandar codificacion php convention

php - psr2 - psr-0



Estándar PSR-2 para condiciones if largas (9)

No encontré ningún estándar para este caso:

if ($a == $b && $b == $c && $c == $d && $g == $d) { }

o

if (($a == $b && $b == $c) && ($c == $d && $g == $d)) { }

Imagine que los var-nombres son más largos y se exceden 80 letras. ¿Cómo debería manejar esto? Podría verse así:

if ( $a == $b && $b == $c && $c == $d && $g == $d ) { }


Editar

Un año después, recomiendo rescribir tu código para tener una declaración if más corta. A través de variables o llamadas a funciones.

Original

Entré en esta situación, así que decidí ir con el siguiente formato:

if ( $a == $b && $b == $c && $c == $d && $g == $d) { }

Pero utilizo phpcbf, que transformó (siguiendo el estándar PSR2) el código anterior en:

if ($a == $b && $b == $c && $c == $d && $g == $d) { }

Quería saber más: ¿cómo sabe que este es el comportamiento esperado por el estándar si no está escrito en ninguna parte? Bueno, la respuesta es simple: el caso es tomado en cuenta por el estándar, por la siguiente oración:

NO DEBE haber un espacio después del paréntesis de apertura

Esto explica por qué el segundo fragmento es el único y el único que sigue el estándar PSR-2, según lo declarado por php-fig .


Mi enfoque favorito es eliminar las subexpresiones de la declaración IF, de la siguiente manera:

$c1 = $a == $b; $c2 = $b == $c; $c3 = $c == $d; $c4 = $g == $d; if ($c1 && $c2 && $c3 && $c4) { }

Este enfoque también lo hará más fácil de depurar.

El segundo caso que expone es equivalente al primero debido a la propiedad asociativa de los operadores lógicos . Por lo tanto, $a && $b && $c es lo mismo que ($a && $b) && $c , que es lo mismo que $a && ($b && $c)


No hay recomendación / convención para este caso, y como Halcyon ya mencionó, este es un caso bastante excepcional.

Sin embargo, hay una recomendación para una llamada a función con una larga lista de parámetros:

Las listas de argumentos PUEDEN dividirse en varias líneas, donde cada línea subsiguiente se sangra una vez. Al hacerlo, el primer elemento de la lista DEBE estar en la siguiente línea, y DEBE haber solo un argumento por línea.

<?php $foo->bar( $longArgument, $longerArgument, $muchLongerArgument );

Entonces, si tuviera que crear un enunciado if similar al tuyo, haría esto:

if ( $a == $b && $b == $c && $c == $d && $g == $d ) { // do something }

Como puede ver, esto es casi lo mismo que la solución que propuso usted mismo, pero prefiero agregar los operadores && después de las condiciones.


Personalmente, prefiero

if ($a == $b && $b == $c && $c == $d && $g == $d ) { // code here... }

Para cada línea, comienzas con el doble ampersand, lo que indica que la siguiente declaración es independiente de las demás. Si coloca el ampersand al final de la línea, puede ser menos obvio cuando las líneas varían mucho en longitud.

Por ejemplo;

if ($a == $b && $b == $c && $thisisamuchlongerstatementbecauseofthisvar == $d && $g == $d ) { // code here... }

En este caso, debe escanear el código más para saber que cada línea está conectada por un doble ampersand.


Prefiero hacerlo en este estilo:

diff --git a/3.php b/3.php index 367c57c..2a40c3a 100644 --- a/3.php +++ b/3.php @@ -6,6 +6,7 @@ if ( $something instanceof SomeClass && $something->has($someNumber) && $someNumber > 42 + && $anotherCase ) { // do something

Pero, de nuevo, mantenga su if es lo más simple posible.

Tal vez es una mejor idea separar una gran condición en múltiples if''s.

Para su pregunta, crearía una función que toma una matriz y devuelve verdadero si se cumplen todos && . Entonces, en mi código principal, tendrías

diff --git a/4.php b/4.php index f654780..2b9e0c5 100644 --- a/4.php +++ b/4.php @@ -5,7 +5,8 @@ if ( $something instanceof SomeClass && $something->has($someNumber) && - $someNumber > 42 + $someNumber > 42 && + $anotherCase ) { // do something


Prefiero poner operadores lógicos en sentencias largas al principio de la línea, principalmente para la legibilidad y un mejor comportamiento en el control de versiones.

Tenga en cuenta que, como también se menciona en las otras respuestas, generalmente es un olor codificado tener declaraciones largas si. Sin embargo, a veces tienes que hacerlo, o el código ya está allí y no puedes volver a escribirlo, así que si ya es algo malo, entonces no es un desastre.

Además, estas cosas se aplican a las declaraciones if con solo un "y" donde los diferentes elementos son tan largos que aún necesita dividirlo en varias líneas (por ejemplo, variable larga o nombres de clase).

if (condition1 || (condition2_1 && condition2_2 && condition2_3) && (c3 && c4) { // do something }

Legibilidad : como todos los operadores lógicos están agrupados verticalmente, puede ver instantáneamente qué operador está en cada línea. A medida que su ojo escanea el código, puede moverse verticalmente y solo necesita moverse horizontalmente cuando hay un nivel lógico extra real.

Si los operadores están al final de la línea, su ojo debe moverse hacia adelante y hacia atrás al azar entre líneas de longitud irregular.

Mejor comportamiento en el control de versiones : cuando se agrega una cláusula adicional en la parte inferior de la instrucción if, esto se traduce en 1 línea agregada y 0 eliminada en el control de la versión.

$arr = [$a => $b, $b => $c, $c => $d]; // or you can create array of arrays [[$a, $b], [$b, $c] ...] if (allTrue($arr)) // do something

Si coloca operadores lógicos al final, se agregarán 2 líneas y se eliminará 1. Eso a su vez oscurece información útil: su mensaje de compromiso para el último cambio se mostrará para ambas líneas cuando Git haga una anotación, por lo que tendría que ir a la versión anterior para ver el mensaje de confirmación para la línea a la que agregó el operador.

if ( $something->getValue() === ''some_value'' || ( $something instanceof SomeClass && $something->has($someNumber) && $someNumber > 42 ) ) { // do something }


Sugeriría que intentes pensar en la operación en términos diferentes. Por ejemplo:

if (count(array_unique([$a, $b, $c, $d, $g])) == 1)

Quizás descubra que puede expresar todo el algoritmo como una operación más en un conjunto, usar una matriz en lugar de variables individuales y usar operaciones lógicas en el conjunto como se muestra arriba. Eso puede conducir a un código drásticamente diferente y más legible.

Otro ejemplo de refactorización:

namespace My; UnexpectedValueException::assertAllEqual($a, $b, $c, $d, $g); class UnexpectedValueException extends /UnexpectedValueException { public static function assertAllEqual(/* $value, ... */) { $args = func_get_args(); if (count(array_unique($args)) > 1) { throw new static(sprintf(''[%s] are not all equal'', join('', '', $args))); } } }


Una buena manera en mi opinión es hacer algo como esto

function testString($string) { // define the if criteria $criteria = [ // 0: string starts with A substr($string, 0, 1) == ''A'', // 1: string ends with Z substr($string, -1, 1) == ''Z'', // 2: string length is 10 strlen($string) == 10 ]; // if the array contains false, at leat one creteria failed return !in_array(false, $criteria); }

Por supuesto, esto se puede usar sin la función de envoltura también. Es muy fácil de depurar: simplemente var_dump la variable $ criteria, y obtendrá la lista de lo que tuvo éxito y lo que falló.

Resultados

testString(''ABCDEFGXYZ'') // true testString(''ABCDEFXYZ'') // false testString(''BCDEFGHXYZ'') // false

Esto es solo un ejemplo, para algo simple como esta detección de cadenas, debería usar expresiones regulares.


Yo también lo prefiero al principio:

if ( self::LOG_ALL || ( self::DEBUG__EXECUTION_TIME__IS_ENABLED && (self::DEBUG__EXECUTION_TIME__THRESHOLD_SECONDS < $trxDurinationSeconds) ) ) { doSomething(); }