/ / ¿Por qué PHP evalúa $ b y $ b = $ b de manera diferente cuando se usa con $ b ++ en el índice de matriz - php, orden de evaluación

¿Por qué PHP evalúa $ b y $ b = $ b de manera diferente cuando se usa con $ b ++ en el índice de matriz - php, orden de evaluación

No puedo comprender la lógica de evaluación en el código que se detalla a continuación. ¿Alguien sabe por qué PHP evalúa $b y $b = $b diferente en este caso?

He leído una serie de preguntas aquí en SO y revisé el Manual de PHP. Al hacerlo, he llegado a comprender que "PHP no especifica (en el caso general) en qué orden se evalúa una expresión" y eso "el comportamiento puede cambiar entre versiones de PHP o dependiendo del código que lo rodea". Sin embargo, no creo que eso se aplique a esta situación. ¿O sí?

Ser el primero en admitir que este no es el problema de tu codificación diaria, todavía tengo curiosidad. Tropecé con eso tratando de hacer algo código de golf.

$a = [[00, 01, 02, 03],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33]];

$b = 2;
echo $a[$b][$b++], PHP_EOL;

$b = 2;
echo $a[$b=$b][$b++], PHP_EOL;

Salida - PHP 5.5.14:

32
22

Respuestas

10 por respuesta № 1

Esto se ve como el ejemplo en el manual usado para demostrar Orden indefinido de evaluación. Del manual:

La precedencia y la asociatividad del operador solo determinan cómo se agrupan las expresiones, no especifican un orden de evaluación. PHP no especifica (en el caso general) enpara qué orden se evalúa una expresión y se debe evitar el código que asume un orden específico de evaluación, porque el comportamiento puede cambiar entre versiones de PHP o dependiendo del código circundante.

Énfasis añadido

El ejemplo que dan:

<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3

$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>

Obtiene el resultado que tiene porque en el primer ejemplo, el índice $b++ está siendo determinado primero, mientras que en el segundo, el índice $b=$b es primero.

nótese bien

Como para por qué esto es, creo que una razón posible se explica por esta nota en la misma página del manual:

Aunque = tiene una precedencia menor que la mayoría de los otros operadores, PHP todavía permitirá expresiones similares a las siguientes: if (! $ A = foo ()), en cuyo caso el valor de retorno de foo () se pone en $ a.

Creo que les falta una última palabra crucial allí: primero (sin, para mí leer la nota pierde un poco de significado).

Siguiendo las propias reglas de PHP, y asumimos una orden FIFO, !$a debe ser evaluado primero. Si $a es actualmente null o undefined, entonces !$a será igual true (será evaluado y ese resultado será desechado). Siguiendo esto, foo() será evaluado, y su valor de retorno será asignado a $a (incluso si estamos asumiendo FIFO, foo() debe evaluarse primero si su resultado debe asignarse a algo). El resultado de esta tarea será evaluado por if, y dará como resultado exactamente el valor opuesto que el autor quería.

No soy un experto en C, pero un poco de búsqueda también me llevan a esto responder que cita el estándar C90:

(C90, 6.3) "Excepto según lo indicado por la sintaxis o especificado de otra manera más adelante (para el operador de llamada de función (), &&, ||,?:, Y operadores de coma). El orden de evaluación de las subexpresiones y el orden en el cual los efectos secundarios toman el lugar no está especificado "

Como PHP se basa en C, tiene sentido que herede algunas de sus excentricidades.