2013-07-11 7 views
30

Ich habe diesen Code versuchtWarum dekrementiert von NULL nicht negativ in diesem Array?

$a = array_fill(0, 4, NULL); 
$a[0]++; 
++$a[1]; 
$a[2]--; 
--$a[3]; 
var_dump($a); 

Ergebnis:

array(4) { 
    [0]=> int(1) 
    [1]=> int(1) 
    [2]=> NULL 
    [3]=> NULL 
} 

Warum Wert von 2 und 3 Index nicht negativ ist?

+3

Warum erwarten Sie die _index_ negativ zu gehen? Die _values_ gehen nicht negativ, weil 'NULL' in PHP wirklich seltsam ist. Es hat nichts mit der losen Typologie der Sprache zu tun. – Bojangles

+4

Das OP erwartet nicht, dass _index_ negativ ist, sondern die von diesen Indizes angegebenen Werte. – marekful

+7

das ist ein Kandidat für die Aufnahme auf http://phpsadness.com/. – SirDarius

Antwort

14

die Quelle verwenden, Luke

Wie üblich liegt die Antwort in der Quelle. PHP verwendet die folgenden beiden Funktionen intern die Inkrement- und Dekrement-Operationen auszuführen:

ZEND_API int increment_function(zval *op1)

ZEND_API int decrement_function(zval *op1)

Diese Operationen das op1 Argument modifizieren, basierend auf ihrem Typ (NULL ist ein Typ);

case IS_NULL: 
    ZVAL_LONG(op1, 1); 
    break; 

Der obige Code ändert sich die Art der op1 in eine Reihe und setzt den Wert auf 1: innerhalb increment_function() können Sie den folgenden Zweig in the code sehen.

Umgekehrt decrement_function() bietet keine solche Niederlassung und damit die default action wird ausgeführt:

default: 
    return FAILURE; 

diesen Code ausführen, werden eigentlich keine feststellbaren Fehler ergeben, da die Rückgabewerte in der Zend VM absorbiert werden, aber Die Variable wird definitiv auch nicht aktualisiert.

Es ist kein Bug (tm)

Sie überrascht, dass dieses Verhalten zu wissen sein, einschließlich, dass für Boolesche Werte, ist eigentlich documented:

Hinweis: Der Zuwachs/Dekrementoperatoren wirken sich nicht auf boolesche Werte aus. Die Dekrementierung der NULL Werte hat keine Auswirkungen, aber die Erhöhung der Werte führt zu 1.

In Bezug auf booleans:

$a = true; 
var_dump($a--); // true 
$a = false; 
var_dump($a++); // false 

In Bezug auf Strings:

$letter = 'A'; 
var_dump(++$letter); // B 
var_dump(--$letter); // B 
+11

Es ist kein Fehler, weil es dokumentiert ist? – soc

+3

@soc [Was ist ein Softwarefehler?] (Http://en.wikipedia.org/wiki/Software_bug): Ein Softwarefehler ist ein Fehler, ein Fehler, ein Fehler oder eine Störung in einem Computerprogramm oder in einem System, das einen falschen oder ** unerwartetes ** Ergebnis oder bewirkt, dass es sich ** unbeabsichtigt ** verhält. Aber da es dokumentiert ist, ist es ein erwartetes ** und ** beabsichtigtes ** Verhalten. – HamZa

+1

@soc Die leichte Ironie in diesem Teil mag auf blinde Augen gefallen sein, also habe ich einen leichten Schnitt gemacht. Das heißt, ich bin überrascht, dass Sie von dieser Frage angezogen werden, wenn Sie [früher] (http://stackoverflow.com/questions/2968913/which-language-to-choose-for-a-live-web-application/2969493 # 2969493) [Beiträge] (http://Stackoverflow.com/a/3922387/1338292) zu diesem Tag ;-) –

22

seltsam, aber documented auf der Erhöhungs/Dekrementieren Operatoren PHP doc Seite:

Hinweis: Die Erhöhung/Dekrementoperatoren haben keinen Einfluss auf Boolesche Werte. Das Dekrementieren von NULL-Werten hat keine Auswirkung, aber das Inkrementieren dieser Ergebnisse ergibt 1.

+9

Dokumentiert -> kein Fehler ;-) – zerkms

+5

@zerkms aber das sehr zu sagen mindestens, eine ungeheuerliche Verletzung des [Prinzip des geringsten Erstaunens] (https://en.wikipedia.org/wiki/Principle_of_least_astonishment) – fvu

3

Seltsam. Ich kenne ihren entscheidenden Faktor nicht, aber wenn man sich die source code anschaut, sieht man, dass wenn es sich um einen NULL handelt, dieser auf 1 gesetzt wird (nicht inkrementiert).

case IS_NULL: 
    ZVAL_LONG(op1, 1); 
    break; 

Die decrement Funktion mit NULL gar nicht umgehen und geht direkt zum Scheitern:

default: 
    return FAILURE; 

Wie andere schon erwähnt, ist es documented.

Hinweis: Die Erhöhung/Dekrementoperatoren haben keinen Einfluss auf Boolesche Werte. Die Dekrementierung der NULL Werte hat keine Auswirkungen, aber die Erhöhung der Werte führt zu 1.

Verwandte Themen