/ / Warum bewertet PHP $ b und $ b = $ b anders, wenn es mit $ b ++ im Array-Index verwendet wird - php, order-of-evaluation

Warum bewertet PHP $ b und $ b = $ b anders, wenn es mit $ b ++ im Array-Index verwendet wird - php, order-of-evaluation

Ich kann die Auswertelogik im unten aufgeführten Code nicht erfassen. Weiß jemand, warum PHP bewertet? $b und $b = $b anders in diesem Fall?

Ich habe hier bei SO eine Reihe von Fragen gelesen und die PHP-Handbuch. Das habe ich verstanden "PHP spezifiziert nicht (im allgemeinen Fall) in welcher Reihenfolge ein Ausdruck ausgewertet wird" und das "Das Verhalten kann sich zwischen PHP-Versionen oder abhängig vom umgebenden Code ändern". Ich glaube aber nicht, dass das für diese Situation gilt. Oder doch?

Als der erste, der dies zugibt, mag das nicht dein alltägliches Coding-Thema sein, ich bin immer noch neugierig. Stolperte darüber, es zu versuchen Code Golf spielen.

$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;

Ausgabe - PHP 5.5.14:

32
22

Antworten:

10 für die Antwort № 1

Das sieht aus wie das Beispiel in der Handbuch zum Demonstrieren benutzt Undefinierte Reihenfolge der Auswertung. Aus dem Handbuch:

Operatorpräzedenz und Assoziativität bestimmen nur, wie Ausdrücke gruppiert werden, sie geben keine Reihenfolge der Auswertung an. PHP spezifiziert (im allgemeinen Fall) nicht inIn welcher Reihenfolge ein Ausdruck ausgewertet wird und welcher Code eine bestimmte Reihenfolge der Auswertung annimmt, sollte vermieden werden, da sich das Verhalten zwischen PHP-Versionen oder abhängig vom umgebenden Code ändern kann.

Betonung hinzugefügt

Das Beispiel, das sie geben:

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

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

Sie bekommen die Ausgabe, die Sie sind, weil im ersten Beispiel der Index $b++ wird bestimmt zuerst, während im zweiten der Index $b=$b ist zuerst.

NB

Wie für Warum Dies ist, glaube ich, ein möglicher Grund wird durch diesen Hinweis auf der gleichen Handbuchseite erklärt:

Obwohl = hat eine niedrigere Priorität als die meisten anderen Operatoren, PHP erlaubt immer noch Ausdrücke ähnlich der folgenden: if (! $ A = foo ()), in diesem Fall wird der Rückgabewert von foo () in $ a gesetzt.

Ich glaube, dass sie dort ein entscheidendes letztes Wort vermissen: zuerst (Ohne, für mich verliert das Lesen der Nachricht ein wenig an Bedeutung).

Nach den eigenen Regeln von PHP und wir nehmen eine FIFO-Reihenfolge an, !$a sollte zuerst ausgewertet werden. Ob $a ist gerade null oder undefined, dann !$a wird gleich sein true (Es wird ausgewertet und das Ergebnis wird verworfen). Danach foo() wird ausgewertet und sein Rückgabewert wird zugewiesen $a (Auch wenn wir FIFO annehmen, foo() muss zuerst ausgewertet werden, wenn sein Ergebnis etwas zugewiesen werden soll). Das Ergebnis dieser Aufgabe wird von bewertet ifund wird genau den entgegengesetzten Wert ergeben, den der Autor wollte.

Ich bin kein C-Experte, aber ein bisschen Suchen führt mich auch dazu Antworten was den C90-Standard zitiert:

(C90, 6.3) "Außer wie angegeben durch die Syntax oder anderweitig später angegeben (für den Funktionsaufrufoperator (), &&, ||,?:, Und Kommafunktionen) die Reihenfolge der Auswertung von Teilausdrücken und die Reihenfolge, in der Nebenwirkungen auftreten Ort sind beide unspezifiziert "

Da PHP auf C basiert, macht es Sinn, dass es einige seiner Exzentrizitäten erben würde.