tabla - que significa-> en php
Operador ternario dejó asociatividad (5)
En el manual de PHP, encuentro la siguiente ''nota contribuida por el usuario'' en "Operadores".
Tenga en cuenta que en php el operador ternario?: Tiene una asociatividad a la izquierda, a diferencia de C y C ++, donde tiene la asociatividad a la derecha.
No puede escribir código como este (como puede haberse acostumbrado en C / C ++):
<?php $a = 2; echo ( $a == 1 ? ''one'' : $a == 2 ? ''two'' : $a == 3 ? ''three'' : $a == 4 ? ''four'' : ''other''); echo "/n"; // prints ''four''
En realidad lo intento y realmente imprime four
. Sin embargo, no pude entender la razón detrás de esto y todavía siento que debería imprimir two
u other
.
¿Alguien puede explicar qué está pasando aquí y por qué está imprimiendo ''cuatro''?
¿Porque toda tu expresión se evalúa como si fuera (......) ? ''four'' : ''other''
(......) ? ''four'' : ''other''
. Dado que el primer elemento es probablemente algo sincero, te da ''four''
. En lenguajes más sensatos, ?:
dónde ?:
Tiene asociatividad correcta, la expresión completa se evalúa como si fuera $a == 1 ? ''one'' : (......)
$a == 1 ? ''one'' : (......)
, donde si $a
no es 1
, vas a probar otras cosas.
En cualquier lenguaje sensato, el operador ternario es asociativo por derecho, de modo que usted esperaría que su código se interprete así:
$a = 2;
echo ($a == 1 ? ''one'' :
($a == 2 ? ''two'' :
($a == 3 ? ''three'' :
($a == 4 ? ''four'' : ''other'')))); # prints ''two''
Sin embargo, el operador ternario de PHP es extrañamente asociativo a la izquierda, de modo que su código es en realidad equivalente a esto:
<?php
$a = 2;
echo (((($a == 1 ? ''one'' :
$a == 2) ? ''two'' :
$a == 3) ? ''three'' :
$a == 4) ? ''four'' : ''other''); # prints ''four''
En caso de que aún no esté claro, la evaluación es la siguiente:
echo ((((FALSE ? ''one'' :
TRUE) ? ''two'' :
$a == 3) ? ''three'' :
$a == 4) ? ''four'' : ''other'');
echo ((( TRUE ? ''two'' :
$a == 3) ? ''three'' :
$a == 4) ? ''four'' : ''other'');
echo (( ''two'' ? ''three'' :
$a == 4) ? ''four'' : ''other'');
echo ( ''three'' ? ''four'' : ''other'');
echo ''four'';
Esto es lo que se me ocurrió para ayudarme a entender la asociatividad de izquierda frente a derecha para el operador ternario.
// PHP
$a = "T";
$vehicle = $a == "B" ? "bus" :
$a == "A" ? "airplane" :
$a == "T" ? "train" :
$a == "C" ? "car" :
$a == "H" ? "horse" : "feet";
// (as seen by the PHP interpreter)
// INITIAL EXPRESSION: ((((($a == "B" ? "bus" : $a == "A") ? "airplane" : $a == "T") ? "train" : $a == "C") ? "car" : $a == "H") ? "horse" : "feet");
// STEP 1: (((((FALSE ? "bus" : FALSE) ? "airplane" : TRUE) ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 2: ((((FALSE ? "airplane" : TRUE) ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 3: (((TRUE ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 4: (("train" ? "car" : FALSE) ? "horse" : "feet")
// STEP 5: ("car" ? "horse" : "feet")
// FINAL EVALUATION: ("horse")
// If you used the initial expression here (with the parenthesis) in a different language, it would also evaluate to "horse."
echo $vehicle; // gives us "horse"
Esto es a diferencia de:
// EVERY OTHER LANGUAGE
var a = "T";
var vehicle = a == "B" ? "bus" :
a == "A" ? "airplane" :
a == "T" ? "train" :
a == "C" ? "car" :
a == "H" ? "horse" : "feet";
// (as seen by the other language''s interpreter)
// INITIAL EXPRESSION: (a == "B" ? "bus" : (a == "A" ? "airplane" : (a == "T" ? "train" : (a == "C" ? "car" : (a == "H" ? "horse" : "feet")))));
// STEP 1: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : (FALSE ? "car" : (FALSE ? "horse" : "feet")))))
// STEP 2: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : (FALSE ? "car" : "feet"))))
// STEP 3: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : "feet")))
// STEP 4: (FALSE ? "bus" : (FALSE ? "airplane" : "train"))
// STEP 5: (FALSE ? "bus" : "train")
// FINAL EVALUATION: ("train")
// If you used the initial expression here (with the parenthesis) in PHP, it would also evaluate to "train."
console.log(vehicle); // gives us "train"
Si observa, en el ejemplo de PHP, la expresión más interna está a la izquierda, y en el segundo ejemplo, la expresión más interna está a la derecha. Cada paso evalúa la siguiente expresión más interna hasta que haya un solo resultado. ¡Los paréntesis son claramente muy importantes si va a anidar operaciones ternarias en PHP!
No pude envolver mi cabeza alrededor del ejemplo de:
https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
Así que vine aquí y todavía no podía rodear mi cabeza, así que tuve que atravesarlo.
@amadan tiene la mejor respuesta, imo.
Esto imprime caballo, no tren.
// 0
$arg = ''T'';
$vehicle =
$arg == ''B'' ? ''bus'' :
$arg == ''A'' ? ''airplane'' :
$arg == ''T'' ? ''train'' :
$arg == ''C'' ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 1
$vehicle =
> FALSE ? ''bus'' :
$arg == ''A'' ? ''airplane'' :
$arg == ''T'' ? ''train'' :
$arg == ''C'' ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 2
$vehicle =
FALSE ? ''bus'' :
> FALSE ? ''airplane'' :
$arg == ''T'' ? ''train'' :
$arg == ''C'' ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 3
$vehicle =
> (FALSE? ''bus'' : FALSE? ''airplane'' : TRUE)? ''train'' :
$arg == ''C'' ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 4
$vehicle =
> true ? ''train'' :
$arg == ''C'' ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 5
$vehicle =
> (''train'' : $arg == ''C'') ? ''car'' :
$arg == ''H'' ? ''horse'' :
''feet'' ;
// 6
$vehicle =
> (true ? ''car'' : $arg == ''H'') ? ''horse'' :
''feet'' ;
// 7
$vehicle =
> (true) ? ''horse'' : ''feet'' ;
Puedes ver lo que significa asociación asociativa en el paso 5, si lo entiendo correctamente.
Si agrega paréntesis, el problema se resolverá. Mira el siguiente ejemplo:
Sin los paréntesis, la calificación siempre es D cuando las marcas son mayores que 50, pero funciona bien para las marcas <= 49.
Para hacer que el programa funcione como debería, he agregado paréntesis. Es muy fácil saber cuántos paréntesis debe ingresar si se escribe así.
<?php
$marks_obtained = 65;
$grade = null;
//Use parentheses () otherwise the final grade shown will be wrong.
//Excluding the first line, for each additional line,
//we add a parenthesis at the beginning of each line and a parenthesis at the end of the statement.
echo $grade = $marks_obtained >= 90 && $marks_obtained <= 100 ? "A+"
: ($marks_obtained <= 89 && $marks_obtained >= 80 ? "A"
: ($marks_obtained <= 79 && $marks_obtained >= 70 ? "B"
: ($marks_obtained <= 69 && $marks_obtained >= 60 ? "C"
: ($marks_obtained <= 59 && $marks_obtained >= 50 ? "D"
: "F"))))
?>