/ / Perché PHP valuta $ b e $ b = $ b in modo diverso se usato con $ b ++ nell'indice array - php, order-of-evaluation

Perché PHP valuta $ b e $ b = $ b in modo diverso se usato con $ b ++ nell'indice array - php, order-of-evaluation

Non riesco a cogliere la logica di valutazione nel codice elencato di seguito. Qualcuno sa perché PHP valuta $b e $b = $b diversamente in questo caso?

Ho letto una serie di domande qui su SO e ho controllato il Manuale PHP. Così facendo, sono arrivato a capirlo "PHP non specifica (nel caso generale) in quale ordine viene valutata un'espressione" e quello "il comportamento può cambiare tra le versioni di PHP o in base al codice circostante". Non credo che ciò si applichi a questa situazione. O lo fa?

Essere il primo ad ammettere che questo potrebbe non essere il tuo problema quotidiano di codifica, sono ancora curioso. Ci siamo imbattuti in esso cercando di fare un po ' codice 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;

Output - PHP 5.5.14:

32
22

risposte:

10 per risposta № 1

Questo sembra l'esempio nel Manuale usato per dimostrare Ordine di valutazione indefinito. Dal manuale:

La precedenza e l'associatività degli operatori determinano solo il modo in cui le espressioni sono raggruppate, non specificano un ordine di valutazione. PHP non (nel caso generale) specifica inquale ordine viene valutata un'espressione e il codice che presuppone uno specifico ordine di valutazione deve essere evitato, poiché il comportamento può cambiare tra le versioni di PHP o in base al codice circostante.

Enfasi aggiunta

L'esempio che danno:

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

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

Stai ottenendo l'output che sei perché nel primo esempio, l'indice $b++ è stato determinato primo, mentre nel secondo l'indice $b=$b è il primo

NB

Quanto a perché questo è, credo che una possibile ragione sia spiegata da questa nota sulla stessa pagina di manuale:

Sebbene = abbia una precedenza inferiore rispetto alla maggior parte degli altri operatori, PHP consentirà comunque espressioni simili alla seguente: if (! $ A = foo ()), nel qual caso il valore di ritorno di foo () viene messo in $ a.

Credo che ci manchi un'ultima parola cruciale lì: primo (senza, a me leggere la nota perde un po 'di significato).

Seguendo le stesse regole di PHP, e assumiamo un ordine FIFO, !$a dovrebbe essere valutato prima Se $a è attualmente null o undefined, poi !$a sarà uguale true (sarà valutato e il risultato sarà gettato via). Seguendo quello, foo() sarà valutato e verrà assegnato il suo valore di ritorno $a (anche se assumiamo FIFO, foo() deve essere valutato per primo se il risultato deve essere assegnato a qualcosa). Il risultato di questo incarico sarà valutato da ife si tradurrà esattamente nel valore opposto che l'autore voleva.

Non sono un esperto di C, ma un po 'di ricerca mi porta anche a questo risposta che cita lo standard C90:

(C90, 6.3) "Tranne come indicato dalla sintassi o altrimenti specificato in seguito (per gli operatori di chiamata di funzione (), &&, ||,?:, E virgola). L'ordine di valutazione delle sottoespressioni e l'ordine in cui gli effetti collaterali prendono i posti sono entrambi non specificati "

Poiché PHP è basato su C, ha senso che erediti alcune delle sue eccentricità.