2012-01-04 22 views
39

Algo que realmente me gustaría saber pero que nunca descubrí son atajos en PHP.PHP - If/else, for, foreach, while - ¿sin llaves?

Actualmente estoy codificando una función con un bucle foreach con una sola instrucción dentro. Traté de omitir las llaves como lo puedes hacer en estructuras de control if/else y funciona. Sin errores.

foreach($var as $value) 
    $arr[] = $value; 

Ahora traté de usarlo de la misma manera pero poniendo un bloque if/else dentro de él. De nuevo, funciona y no hay errores.

foreach($var as $value) 
    if(1 + 1 == 2) { 
     $arr[] = $value; 
    }; 

Entonces, pensé "¿por qué funciona esto?" y omitió el punto y coma de cierre. Aún trabajando. Así que traté de usar la instrucción if/else sin llaves dentro del ciclo foreach y de nuevo, aún funcionando y sin errores. Pero, ¿el ciclo foreach realmente está cerrado/terminado ahora?

foreach($var as $value) 
    if(1 + 1 == 2) 
     $arr[] = $value; 

Al menos omite el punto y coma de cierre una y otra (como se esperaba) se produjo un error de análisis.

Así que mi gran pregunta es: ¿cuándo puedo omitir las llaves y en qué estructura/lazo/función? Sé que definitivamente puedo hacerlo en if y else. Pero ¿qué pasa con while, for y foreach?

Y sí, ya sé que no es seguro, inteligente, lo que código sin llaves y hay atajos como $condition ? true : false; y if: doSomething(); endif;, endfor; y endforeach;. No quiero aprender sobre los shorthands, solo quiero entender las condiciones sobre cuándo y dónde es posible omitir las llaves.

+3

Por cierto, no es necesario poner un punto y coma después de un corchete de cierre. El significado sintáctico de esto es agregar una declaración vacía entre ellos. Esto es cierto para todos los lenguajes tipo C, a excepción de las declaraciones de 'struct' y' class' en C y C++. – Eric

+0

Necesita aprender la diferencia entre las declaraciones y las expresiones para comprender cuándo curlys son omitibles. Y entonces una comprensión sólida de la cohesión de la expresión es necesaria aún. – mario

+0

funciona exactamente como lo dijiste :) –

Respuesta

68

Cuando omite las llaves, solo tratará la siguiente declaración como el cuerpo de la condición.

if ($x) echo 'foo'; 

es lo mismo que

if ($x) { echo 'foo'; } 

pero recuerde que

if ($x) 
    echo 'foo'; 
    echo 'bar'; 

se siempre de impresión "barra"

Internamente es al revés: if sólo se mira la siguiente expresión, pero PHP trata cada cosa en {} como una única expresión "agrupada".

Lo mismo para las otras sentencias de control (foreach, y así sucesivamente)

+0

Muy buena y breve explicación, gracias! :) ¿Está trabajando en todas las estructuras de control? – headacheCoder

+0

Debería. Actualmente no sé (y no puedo probar) qué pasa con 'do {} while ($ X);', o 'switch'. – KingCrunch

+0

@headacheCoder Sí, funciona para 'for',' while', 'foreach' y' if'. También es así para cada idioma con una sintaxis similar a C. Tome nota de la respuesta de @tkone, acerca de cómo es una buena práctica usar siempre llaves. – Eric

0

Es posible cuando se tiene sólo una expresión después de su cláusula/

Por ejemplo,

foreach($var as $value) 
    if(1 + 1 == 2) { 
     $arr[] = $value; 
    }; 

es correcto, pero

no es, y php intérprete pensar que if extracto está fuera foreach

1

Para las declaraciones de una sola línea.

Si ha intentado hacer

foreach($array as $x => $y) 
    $do_something = $x; 
    $do_something_else = $y; 

Si no me equivoco el intérprete PHP tomará la segunda línea bajo la instrucción foreach como fuera de los apoyos implícitas

Debido a la sangría si vino volver a este código en una fecha posterior, u otro desarrollador miró su trabajo sería confuso.

Como tal, generalmente es aconsejable usar llaves con estas declaraciones. Ahorrará dolores de cabeza/confusión posteriores

+0

Tienes razón. La segunda línea no está dentro del bucle. Solo la siguiente expresión es. – CommandZ

4

Omito llaves en mis plantillas de PHP. P.ej. puede usar bucles de la siguiente manera:

<ul> 
    <?php foreach ($var as $value): ?> 
     <li><?php echo $value; ?></li> 
    <?php endforeach; ?> 
</ul> 
+9

la sintaxis alternativa es algo diferente. – KingCrunch

+1

El OP incluso dijo que sabía acerca de la sintaxis alternativa y de eso no se trataba la pregunta. – CommandZ

25

Hay lugares donde puede, pero nunca debe.

Explícito es siempre mejor que implícito.

Quién sabe cuándo tendrá que volver atrás y modificar el código anterior. Es muy fácil perder esas cosas y no hay nada ganado al hacerlo.

10

¡Funcionará bien si solo tiene un argumento adentro !. Pero si quiere omitir la llave, puede usar dos puntos y un final. ejemplo:

if(a < 1) : 
    echo "a is less than 1"; 
else : 
    echo "a is greater than 1"; 
endif; 
0

La respuesta es fácil. Esto es lo mismo en C/C++.

if, if/else, if/else if/else y loops => Si la siguiente instrucción es una sola línea, puede omitir las llaves.

Ex:

for($i= 0; $i<=100; $i++) 
{ 
    if($i % 7 == 0) 
    { 
     echo $i . "<br>"; 
    } 

} 

También se puede escribir de la siguiente manera:

for($i= 0; $i<=100; $i++) if($i % 7 == 0) echo $i . "<br>"; 
2

Usted puede utilizarlo para cosas simples como:

if($a === true) continue; 

Pero por alguna más complicado sub-condiciones que pueden causarle problemas:

$a = false; 
    $b = false; 
    if ($a === true) 
     if ($b === true) 
      echo 1; 
    else 
     echo 2; 

Con el código anterior, esperaría ver "2" como salida, pero no lo hará.

5

Como han dicho que no quieres aprender acerca de respuesta aceptada taquigrafía y da buen ejemplo sobre la omisión de curly braces, pero hay algo que añadir. Como puede ver, está bien omitir curly braces en el caso de if ($x) echo 'foo';. No hay nada de malo con el código, sin rendimiento u otros problemas y otros desarrolladores lo pueden leer.Y el ejemplo también se muestra que si se escribe

if ($x) 
    echo 'foo'; 
    echo 'bar'; 

en lugar de

if ($x) 
    echo 'foo'; 

echo 'bar'; 

Puede encontrarse con resultados no deseados cuando bar que se escribe, mientras que no desea que se imprima y si su código es lleno de tales declaraciones, entonces será más difícil para usted leer su propio código y aún más difícil para otros leerlo.

No quiero aprender sobre la taquigrafía Sólo quiero entender las condiciones sobre cuándo y dónde es posible omitir las llaves.

Estas cosas están estrechamente relacionados así que si realmente quiere entender donde es posible omitir llaves entonces que debería ser imprescindible que usted entiende o no al menos al tanto de la taquigrafía, han leído

  1. PHP Control Structures
  2. The PHP ternary conditional operators and expressions in general

Así que mi gran pregunta es: ¿Cuándo se puede omitir el cur ¿llaves y en qué estructura/lazo/función?

La llave no es necesaria, sin embargo, para la legibilidad y el mantenimiento, muchos desarrolladores consideran que es un mal estilo no incluirlos. Los enlaces previos 2 deberían proporcionarle la información necesaria para tomar sus propias decisiones cuando podría omitir la llave. por ejemplo, no hay nada de malo en seguir los fragmentos de código que hacen exactamente lo mismo.

Con llave de

if (PHP_VERSION_ID < 70000) 
{ 
    print "PHP >= 7.0 required yours is "; 
    print phpversion(); 
    print "\n"; 
    exit(1); 
} 

es igual que

if (PHP_VERSION_ID < 70000) : 
    print "PHP >= 7.0 required yours is "; 
    print phpversion(); 
    print "\n"; 
    exit(1); 
endif; 

o puede utilizar el operador punto

if (PHP_VERSION_ID < 80000) 
    (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1); 

Y se puede hacer uso del operador condicional ternario e incluso omitir if si mismo, además de omitir las llaves

(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1); 

Ya que sólo imprimimos podemos acortar ese y tiras algunos print string functions que estaban aquí en representación de más de una función en la declaración sin llaves

(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is " . phpversion() . "\n") . exit(1); 

a partir de PHP 7 podemos utilizar nula coalescencia operador

(PHP_VERSION_ID > 70000) ?: null ?? (print "PHP >= 7.0 required yours is ".phpversion() . "\n") . exit(1); 

Como se puede ver que hay muchas maneras de obtener exactamente el mismo resultado.Eso no solo aplica para este ejemplo if, sino que también se puede practicar con structure/loop/function. Entonces, no hay una respuesta para su gran pregunta . Uno debería considerar principalmente seguir.

  1. Es fácil de mantener el código que está escribiendo.
  2. ¿Puedes responder por ti mismo? Hay algo que ganas al omitir las llaves.
+0

Hmm, no sabía que agregaron un operador coalescente nulo al operador de Elvis ... ordenado. Pero, ¿qué lado del operador es nulo y permite variables no establecidas en el bloque condicional? – Ber

+1

'$ I_want_value = $ if_im_not_null_use_me ?? $ if_first_is_null_use_me ?? $ if_second_is_null_use_me; 'Entonces puede tener tantas alternativas como usted, que si la variable anterior es NULL; [Nuevas características de PHP 7] (http://php.net/manual/en/migration70.new-features.php) –

+0

Interesante, entonces es un operador infinitivo ... pero ¿funciona en variables indefinidas? Verificare el doc. Creo que ese es el único propósito de tener un operador nulo coalescente, de lo contrario, ¿por qué no utilizar a Elvis? ? :) – Ber

1

Para complementar la respuesta de @Marko, tenga en cuenta que al usar el operador de punto para este asunto, debe encerrar cada operación entre paréntesis, de lo contrario, invertirá el orden.

Por ejemplo, este código a continuación imprimirá PHP >= 7.0 required yours is 5.6.15.

(print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n"); 

Si bien esto imprimirá 5.6.151PHP >= 7.0 required yours is 1.

print("PHP >= 7.0 required yours is ") . print(phpversion()) . print("\n"); 

También puede usar el operador and para que esto funcione. De la misma manera:

if (PHP_VERSION_ID < 70000) 
    print("PHP >= 7.0 required yours is ") and 
    print(phpversion()) and 
    print("\n");