Typ-Jonglieren und (strenge) Vergleiche größer / kleiner als in PHP

115

PHP ist berühmt für sein Typ-Jonglieren. Ich muss zugeben, dass es mich verwirrt, und es fällt mir schwer, grundlegende logische / grundlegende Dinge in Vergleichen herauszufinden.

Zum Beispiel: Wenn $a > $bwahr ist , und $b > $cwahr ist , muss es bedeuten , dass $a > $cist immer wahr zu?

Nach der Grundlogik würde ich ja sagen, aber ich bin so verwirrt, dass ich PHP nicht wirklich vertraue. Vielleicht kann jemand ein Beispiel geben, wo dies nicht der Fall ist?

Ich frage mich auch bei den strengen Operatoren kleiner als und streng größer als (da ihre Bedeutung als streng beschrieben wird, was ich in der Vergangenheit nur aus den Gleichheitsvergleichen wusste), ob es einen Unterschied macht, wenn linke und rechte Operanden ausgetauscht werden streng ungleiche Werte:

# Precondition:
if ($a === $b) {
    throw new Exception(
       'Both are strictly equal - can not compare strictly for greater or smaller'
    );
}

($a > $b) !== ($b > $a)

Für die meisten Typvergleichskombinationen sind diese größeren / kleineren Vergleichsoperatoren nicht dokumentiert, daher war das Lesen des Handbuchs in diesem Fall nicht wirklich hilfreich.

hakre
quelle
Ich denke, Sie möchten diese Zeile korrigieren, um zu sein ($a > $b) !== ($b < $a)?
Walter Tross
ah, ok, also habe ich das falsch verstanden. Muss meine Antwort entsprechend korrigieren. Lustig all diese Leute, die Abhandlungen schreiben anstatt Antworten und Ihre Frage nicht sorgfältig lesen ...
Walter Tross

Antworten:

208

Die Vergleichsoperatoren von PHP weichen in mehrfacher Hinsicht von den computerwissenschaftlichen Definitionen ab:

Um eine Äquivalenzbeziehung zu bilden, == muss sie reflexiv, symmetrisch und transitiv sein:

  • Der PHP- ==Operator ist nicht reflexiv , dh $a == $anicht immer wahr:

    var_dump(NAN == NAN); // bool(false)

    Hinweis: Die Tatsache, dass ein Vergleich NANimmer durchgeführt wird, falseist nicht spezifisch für PHP. Es ist vom IEEE 754-Standard für Gleitkomma-Arithmetik vorgeschrieben ( weitere Informationen ).

  • Der PHP- ==Operator ist symmetrisch , dh $a == $bund $b == $aimmer gleich.

  • PHP- ==Operator ist nicht transitiv , dh aus $a == $bund $b == $cist nicht folgt $a == $c:

    var_dump(true == "a"); // bool(true)
    var_dump("a" == 0);    // bool(true)
    var_dump(true == 0);   // bool(false)

Um eine Teilordnung zu bilden <= / >=muss reflexiv, antisymmetrisch und transitiv sein:

  • Der PHP- <=Operator ist nicht reflexiv , dh $a <= $anicht immer wahr (Beispiel wie für ==).

  • Der PHP- <=Operator ist nicht antisymmetrisch , dh von $a <= $bund $b <= $afolgt nicht $a == $b:

    var_dump(NAN <= "foo"); // bool(true)
    var_dump("foo" <= NAN); // bool(true)
    var_dump(NAN == "foo"); // bool(false)
  • Der PHP- <=Operator ist nicht transitiv , dh von $a <= $bund $b <= $cfolgt nicht $a <= $c(Beispiel wie für ==).

  • Extra: Der PHP- <=Operator ist nicht vollständig , dh beides $a <= $bund $b <= $akann falsch sein:

    var_dump(new stdClass <= new DateTime); // bool(false)
    var_dump(new DateTime <= new stdClass); // bool(false)

Um eine strenge Teilordnung zu bilden < / >muss irreflexiv, asymmetrisch und transitiv sein:

  • Der PHP- <Operator ist irreflexiv , dh er $a < $aist niemals wahr. Beachten Sie, dass dies nur ab PHP 5.4 gilt . Zuvor INF < INFausgewertet zu true.

  • Der PHP- <Operator ist nicht asymmetrisch , dh von $a < $bfolgt nicht !($b < $a)(Beispiel wie für <=nicht antisymmetrisch).

  • Der PHP- <Operator ist nicht transitiv , dh von $a < $bund $b < $cfolgt nicht $a < $c:

    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)
  • Extra: Der PHP- <Operator ist nicht trichotom , dh alle $a < $b, $b < $aund $a == $bkann falsch sein (Beispiel wie für <=nicht vollständig).

  • Extra: PHP- <Operator kann sein kreisförmig , dh es ist möglich, dass $a < $b, $b < $cund $c < $a:

    var_dump(INF < []);           // bool(true)
    var_dump([] < new stdClass);  // bool(true)
    var_dump(new stdClass < INF); // bool(true)

    Hinweis: Im obigen Beispiel wird der Hinweis "Objekt der Klasse stdClass konnte nicht in double konvertiert werden" ausgelöst.

Unter PHP Sadness 52 - Vergleichsoperatoren finden Sie einige schöne Grafiken für die Vergleichsoperatoren von PHP .

Als letzte Anmerkung möchte ich darauf hinweisen , dass es zwei Gleichheiten , dass PHP tut Garantie ( im Gegensatz zu so ziemlich alles andere). Diese beiden gelten immer, einfach weil der Compiler das eine auf das andere reduziert:

($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)
NikiC
quelle
2
Wow, schöne Antwort. Es ist also nicht möglich, logische Ausdrücke mit PHP wie ($a > $b) and ($b > $c)mit zu formulieren $a > $c, obwohl die Dokumentation besagt, dass diese </ >Operatoren sagen, dass sie streng sind ?
hakre
26
IMHO-Operatoren folgen mathematischen Regeln, jedoch nur, wenn dieselben Datentypen verwendet werden. Typ Casting ist das, was hier (und in vielen anderen Situationen) wirklich Verwirrung stiftet. Wenn Zahlen und Zeichenfolgen und spezielle Werte verglichen werden, werden Typkonvertierungen vor den Operatoren durchgeführt, so dass Vergleichsoperatoren streng genommen nicht verwirrend sind. Casting ist ...
ivanhoe
6
@ ivanhoe011 Die Wahrheit ist: Beide sind :) PHPs Vergleichsregeln und PHPs Castingregeln unterscheiden sich , man kann nicht einfach sagen, dass $a == $bdas dasselbe ist wie (type) $a === (type) $b. Ein einfaches Beispiel dafür ist das "15" == "0xf", aber (int) "15" !== (int) "0xf". Und sowohl Vergleichs- als auch Casting-Regeln in PHP sind total verrückt ^^
NikiC
3
@NikiC: Wird natürlich als (int)"0xf"Ganzzahl ausgewertet . Der Vergleich in diesem Beispiel verhält sich genau wie erwartet. Es ist das Casting, das hier verwirrend ist. Ich gebe zu, es war ein echtes Vergleichsproblem, aber es war ein Sonderfall, und es wurde gelöst, wie Sie betont haben. Tolle Antwort .. +100 !== 15(INF < INF) === true
FtDRbwLXw6
1
Ich beschuldige die Entwickler von PHP nicht unbedingt für einige der Entscheidungen, die zu dieser Zeit in Bezug auf Typenzwang Sinn machten ... aber ich denke, die hätten die Ergebnisse dieser Designentscheidungen bemerken und sofort erkennen müssen, dass die Entscheidungen offensichtlich falsch waren. Das offensichtlichste Beispiel ist der Kommentar von @ ravz.
Tschad
88

Es gibt keine streng identischen Vergleichsoperatoren ( >==oder <==) in PHP (mindestens in PHP 5.6.14) , aber es gibt einige Möglichkeiten , eine strenge Typprüfung zu erzwingen, bevor Größer / Niedriger überprüft wird:

  1. Überprüfen Sie beide Variablentypen mit if (gettype($a) === gettype($b))
  2. Erzwingen Sie Ihren benötigten Typcast, z. if ((string)$a === (string)$b)
  3. Erzwingen Sie Ihren benötigten Typ-Jonglage, z. if (($a . '') === ($b . ''))

Beachten Sie Folgendes:

  • Gleitkommapräzision ist begrenzt
  • INF und NAN sind vom Typ floatunter
  • Einige Unendlichkeit entspricht einer anderen Unendlichkeit (seit PHP 5.4)
  • Wissenschaftliche Notation eist immer vom Typ floatund niemalsinteger selbst wenn die Anzahl klein ist
  • Ganzzahlen gehen vorbei PHP_INT_MAX automatisch in konvertiertfloat
  • Schwebt über die Systemgrenzen hinweg INF Wert
  • Undefinierte Variablen sind von Typ und Wert NULL
  • Ganzzahlen mit vorangestelltem 0 werden (gemäß Konvention) von Oktal in Dezimal konvertiert.
  • Das Konvertieren von Zeichenfolgen, die eine Ganzzahl mit einer führenden 0 in eine Ganzzahl enthalten, entfernt die führende0

Liste einiger exotischer Vergleiche:

Sehr eigenartig:
     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  float (NAN) float (-INF) false false false false false false
  float (NAN) float (0) false false false false false false
  float (NAN) float (1) falsch falsch falsch falsch falsch falsch
  float (NAN) float (INF) falsch falsch falsch falsch falsch falsch
  float (NAN) float (NAN) falsch falsch falsch falsch falsch falsch
  float (NAN) int (-1) false false false false false false
  float (NAN) int (0) false false false false false false
  float (NAN) int (1) falsch falsch falsch falsch falsch falsch

Gleich, aber nicht identisch:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) array () false false true true true false
  NULL (NULL) bool (false) false false true true true false
  NULL (NULL) float (0) false false true true true false
  NULL (NULL) int (0) falsch falsch wahr wahr wahr falsch
  NULL (NULL) str ('') falsch falsch wahr wahr wahr falsch
   array () bool (false) false false true true true true false
 bool (false) float (0) false false true true true false
 bool (false) int (0) false false true true true false
   str ('') bool (false) false false true true true false
 bool (false) str ('0') false false true true true false
 float (-INF) bool (true) false false true true true false
  bool (true) float (1) false false true true true false
  float (INF) bool (wahr) falsch falsch wahr wahr wahr falsch
  float (NAN) bool (wahr) falsch falsch wahr wahr wahr falsch
  bool (true) int (-1) false false true true true false
  bool (true) int (1) false false true true true false
  bool (true) str ("\ 0") false false true true true false
  bool (true) str ('+') false false true true true false
  bool (true) str ('-') false false true true true false
  bool (true) str ('01 ') false false true true true false
  bool (true) str ('1') false false true true true false
  bool (true) str ('false') false false true true true false
 str ('text') bool (wahr) falsch falsch wahr wahr wahr falsch
 str ('true') bool (true) false false true true true false
    int (0) float (0) false false true true true true false
  str ("\ 0") float (0) false false true true true false
   str ('') float (0) false false true true true false
   str ('+') float (0) false false true true true false
   str ('-') float (0) false false true true true false
   str ('0') float (0) false false true true true false
 str ('false') float (0) false false true true true false
 str ('text') float (0) false false true true true false
 str ('true') float (0) false false true true true false
    int (1) float (1) false false true true true false
   float (1) str ('01 ') false false true true true false
   float (1) str ('1') false false true true true false
  str ("\ 0") int (0) false false true true true false
   str ('') int (0) false false true true true false
   str ('+') int (0) falsch falsch wahr wahr wahr falsch
   str ('-') int (0) falsch falsch wahr wahr wahr falsch
    int (0) str ('0') falsch falsch wahr wahr wahr falsch
 str ('false') int (0) false false true true true false
 str ('text') int (0) false false true true true false
 str ('true') int (0) false false true true true false
    int (1) str ('01 ') falsch falsch wahr wahr wahr falsch
    int (1) str ('1') falsch falsch wahr wahr wahr falsch
   str ('1') str ('01 ') falsch falsch wahr wahr wahr falsch

Niedriger und größer gleichzeitig?

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  float (NAN) str ("\ 0") wahr wahr wahr wahr falsch falsch
  float (NAN) str ('') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('+') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('-') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('0') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('01 ') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('1') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('false') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('text') wahr wahr wahr wahr falsch falsch
  float (NAN) str ('true') true true true true false false

Gleich UND identisch:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) NULL (NULL) falsch falsch wahr wahr wahr wahr
 float (-INF) float (-INF) false false true true true true
  float (INF) float (INF) falsch falsch wahr wahr wahr wahr

Niedriger oder größer:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) bool (wahr) falsch wahr wahr falsch falsch falsch
 float (-INF) NULL (NULL) wahr falsch falsch wahr falsch falsch
  NULL (NULL) float (1) false true true false false false
  float (INF) NULL (NULL) wahr falsch falsch wahr falsch falsch
  float (NAN) NULL (NULL) wahr falsch falsch wahr falsch falsch
  NULL (NULL) int (-1) falsch wahr wahr falsch falsch falsch
  NULL (NULL) int (1) falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ("\ 0") falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('+') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('-') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('0') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('01 ') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('1') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('false') false true true false false false
  NULL (NULL) str ('text') falsch wahr wahr falsch falsch falsch
  NULL (NULL) str ('wahr') falsch wahr wahr falsch falsch falsch
   array () bool (true) false true true false false false false
 float (-INF) array () false true true false false false
   array () float (0) true false false true false false false
   array () float (1) true false false true false false
  float (INF) array () false true true false false false false
  float (NAN) array () false true true false false false false
   array () int (-1) true false false true false false false
   array () int (0) true false false true false false false
   array () int (1) wahr falsch falsch wahr falsch falsch falsch
   array () str ("\ 0") wahr falsch falsch wahr falsch falsch
   str ('') array () false true true false false false false
   array () str ('+') wahr falsch falsch wahr falsch falsch
   array () str ('-') true false false true false false
   array () str ('0') wahr falsch falsch wahr falsch falsch
   array () str ('01 ') true false false true false false
   array () str ('1') wahr falsch falsch wahr falsch falsch
   array () str ('false') true false false true false false
   array () str ('text') wahr falsch falsch wahr falsch falsch
   array () str ('true') true false false true false false
  bool (wahr) bool (falsch) wahr falsch falsch wahr falsch falsch
 float (-INF) bool (false) true false false true false false
   float (1) bool (false) true false false true false false
  float (INF) bool (false) wahr falsch falsch wahr falsch falsch
  float (NAN) bool (false) wahr falsch falsch wahr falsch falsch
 bool (false) int (-1) false true true false false false
    int (1) bool (false) true false false true false false
 bool (false) str ("\ 0") false true true false false false
 bool (false) str ('+') false true true false false false
 bool (false) str ('-') false true true false false false
 bool (false) str ('01 ') false true true false false false
   str ('1') bool (false) wahr falsch falsch wahr falsch falsch
 bool (false) str ('false') false true true false false false
 str ('text') bool (false) wahr falsch falsch wahr falsch falsch
 str ('true') bool (false) true false false true false false
  bool (true) float (0) true false false true false false
  bool (true) int (0) true false false true false false
   str ('') bool (wahr) falsch wahr wahr falsch falsch falsch
  bool (true) str ('0') true false false true false false
 float (-INF) float (0) false true true false false false
 float (-INF) float (1) false true true false false false
  float (INF) float (-INF) wahr falsch falsch wahr falsch falsch
 float (-INF) int (-1) false true true false false false
 float (-INF) int (0) false true true false false false
 float (-INF) int (1) false true true false false false
 float (-INF) str ("\ 0") false true true false false false
 float (-INF) str ('') false true true false false false
 float (-INF) str ('+') false true true false false false
 float (-INF) str ('-') false true true false false false
 float (-INF) str ('0') false true true false false false
 float (-INF) str ('01 ') false true true false false false
 float (-INF) str ('1') false true true false false false
 float (-INF) str ('false') false true true false false false
 float (-INF) str ('text') false true true false false false
 float (-INF) str ('true') false true true false false false
   float (1) float (0) wahr falsch falsch wahr falsch falsch
  float (INF) float (0) wahr falsch falsch wahr falsch falsch
   float (0) int (-1) true false false true false false
    int (1) float (0) wahr falsch falsch wahr falsch falsch falsch
   float (0) str ('01 ') false true true false false false
   str ('1') float (0) wahr falsch falsch wahr falsch falsch
  float (INF) float (1) wahr falsch falsch wahr falsch falsch
   float (1) int (-1) wahr falsch falsch wahr falsch falsch falsch
   float (1) int (0) wahr falsch falsch wahr falsch falsch falsch
   float (1) str ("\ 0") wahr falsch falsch wahr falsch falsch
   str ('') float (1) false true true false false false
   float (1) str ('+') wahr falsch falsch wahr falsch falsch
   float (1) str ('-') wahr falsch falsch wahr falsch falsch
   float (1) str ('0') wahr falsch falsch wahr falsch falsch
   float (1) str ('false') wahr falsch falsch wahr falsch falsch
 str ('text') float (1) false true true false false false
 str ('true') float (1) false true true false false false
  float (INF) int (-1) wahr falsch falsch wahr falsch falsch
  float (INF) int (0) wahr falsch falsch wahr falsch falsch
  float (INF) int (1) wahr falsch falsch wahr falsch falsch
  float (INF) str ("\ 0") wahr falsch falsch wahr falsch falsch
  float (INF) str ('') wahr falsch falsch wahr falsch falsch
  float (INF) str ('+') wahr falsch falsch wahr falsch falsch
  float (INF) str ('-') wahr falsch falsch wahr falsch falsch
  float (INF) str ('0') wahr falsch falsch wahr falsch falsch
  float (INF) str ('01 ') wahr falsch falsch wahr falsch falsch
  float (INF) str ('1') wahr falsch falsch wahr falsch falsch
  float (INF) str ('false') wahr falsch falsch wahr falsch falsch
  float (INF) str ('text') wahr falsch falsch wahr falsch falsch
  float (INF) str ('true') wahr falsch falsch wahr falsch falsch
    int (0) int (-1) wahr falsch falsch wahr falsch falsch
    int (1) int (-1) wahr falsch falsch wahr falsch falsch falsch
  str ("\ 0") int (-1) wahr falsch falsch wahr falsch falsch
   str ('') int (-1) wahr falsch falsch wahr falsch falsch
   str ('+') int (-1) wahr falsch falsch wahr falsch falsch
   str ('-') int (-1) wahr falsch falsch wahr falsch falsch
   str ('0') int (-1) wahr falsch falsch wahr falsch falsch
   int (-1) str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('1') int (-1) wahr falsch falsch wahr falsch falsch
 str ('false') int (-1) true false false true false false
 str ('text') int (-1) wahr falsch falsch wahr falsch falsch
 str ('true') int (-1) true false false true false false
    int (1) int (0) wahr falsch falsch wahr falsch falsch
    int (0) str ('01 ') false true true false false false
   str ('1') int (0) wahr falsch falsch wahr falsch falsch
    int (1) str ("\ 0") wahr falsch falsch wahr falsch falsch
   str ('') int (1) falsch wahr wahr falsch falsch falsch
    int (1) str ('+') wahr falsch falsch wahr falsch falsch
    int (1) str ('-') wahr falsch falsch wahr falsch falsch
    int (1) str ('0') wahr falsch falsch falsch falsch falsch
    int (1) str ('false') wahr falsch falsch wahr falsch falsch
 str ('text') int (1) falsch wahr wahr falsch falsch falsch
 str ('true') int (1) false true true false false false
   str ('') str ("\ 0") falsch wahr wahr falsch falsch falsch
   str ('+') str ("\ 0") wahr falsch falsch wahr falsch falsch
   str ('-') str ("\ 0") wahr falsch falsch wahr falsch falsch
  str ("\ 0") str ('0') falsch wahr wahr falsch falsch falsch
  str ("\ 0") str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('1') str ("\ 0") wahr falsch falsch wahr falsch falsch
 str ('false') str ("\ 0") wahr falsch falsch wahr falsch falsch
 str ('text') str ("\ 0") wahr falsch falsch wahr falsch falsch
 str ('true') str ("\ 0") wahr falsch falsch wahr falsch falsch
   str ('') str ('+') falsch wahr wahr falsch falsch falsch
   str ('') str ('-') falsch wahr wahr falsch falsch falsch
   str ('') str ('0') falsch wahr wahr falsch falsch falsch
   str ('') str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('') str ('1') falsch wahr wahr falsch falsch falsch
   str ('') str ('false') false true true false false false
   str ('') str ('text') falsch wahr wahr falsch falsch falsch
   str ('') str ('wahr') falsch wahr wahr falsch falsch falsch
   str ('-') str ('+') wahr falsch falsch wahr falsch falsch
   str ('+') str ('0') falsch wahr wahr falsch falsch falsch
   str ('+') str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('1') str ('+') wahr falsch falsch wahr falsch falsch
 str ('false') str ('+') wahr falsch falsch wahr falsch falsch
 str ('text') str ('+') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('+') wahr falsch falsch wahr falsch falsch
   str ('-') str ('0') falsch wahr wahr falsch falsch falsch
   str ('-') str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('1') str ('-') wahr falsch falsch wahr falsch falsch
 str ('false') str ('-') wahr falsch falsch wahr falsch falsch
 str ('text') str ('-') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('-') wahr falsch falsch wahr falsch falsch
   str ('0') str ('01 ') falsch wahr wahr falsch falsch falsch
   str ('1') str ('0') wahr falsch falsch wahr falsch falsch
 str ('false') str ('0') wahr falsch falsch wahr falsch falsch
 str ('text') str ('0') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('0') wahr falsch falsch wahr falsch falsch
 str ('false') str ('01 ') wahr falsch falsch wahr falsch falsch
 str ('text') str ('01 ') wahr falsch falsch wahr falsch falsch
 str ('true') str ('01 ') wahr falsch falsch wahr falsch falsch
   str ('1') str ('false') false true true false false false
 str ('text') str ('1') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('1') wahr falsch falsch wahr falsch falsch
 str ('text') str ('false') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('falsch') wahr falsch falsch wahr falsch falsch
 str ('wahr') str ('text') wahr falsch falsch wahr falsch falsch

$a > $b > $cRätsel, wenn: $anicht größer als ist $c.

A <C: float (NAN)> str ('a')> str ('')
A <C: float (NAN)> str ('a')> str ('1')
A <C: float (NAN)> str ('a')> str ('A')
A <C: float (NAN)> str ('a')> str ('0')
A <C: float (NAN)> str ('1')> str ('')
A <C: float (NAN)> str ('1')> str ('0')
A <C: float (NAN)> str ('A')> str ('')
A <C: float (NAN)> str ('A')> str ('1')
A <C: float (NAN)> str ('A')> str ('0')
A <C: float (NAN)> str ('0')> str ('')
A <C: str ('')> float (NAN)> str ('a')
A <C: str ('')> float (NAN)> str ('1')
A <C: str ('')> float (NAN)> str ('A')
A <C: str ('')> float (NAN)> str ('0')
A <C: str ('a')> str ('')> float (NAN)
A <C: str ('a')> str ('1')> float (NAN)
A <C: str ('a')> str ('A')> float (NAN)
A <C: str ('a')> str ('0')> float (NAN)
A <C: str ('0')> str ('')> float (NAN)
A == C: bool (true)> str ('')> float (NAN)
A == C: bool (true)> str ('')> float (-INF)
A == C: bool (wahr)> str ('')> int (-1)
A == C: bool (true)> str ('')> float (-1)
A == C: bool (true)> array ()> float (NAN)
A == C: bool (true)> array ()> float (INF)
A == C: bool (true)> array ()> float (-INF)
A == C: bool (true)> array ()> str ('a')
A == C: bool (true)> array ()> int (1)
A == C: bool (true)> array ()> float (1)
A == C: bool (true)> array ()> str ('1')
A == C: bool (true)> array ()> str ('A')
A == C: bool (true)> array ()> int (-1)
A == C: bool (true)> array ()> float (-1)
A == C: bool (wahr)> int (0)> float (-INF)
A == C: bool (wahr)> int (0)> int (-1)
A == C: bool (wahr)> int (0)> float (-1)
A == C: bool (wahr)> str ('0')> float (NAN)
A == C: bool (true)> str ('0')> float (-INF)
A == C: bool (wahr)> str ('0')> int (-1)
A == C: bool (wahr)> str ('0')> float (-1)
A == C: bool (true)> float (0)> float (-INF)
A == C: bool (wahr)> float (0)> int (-1)
A == C: bool (wahr)> float (0)> float (-1)
A == C: int (1)> str ('a')> str ('1')
A == C: int (1)> str ('A')> str ('1')
A == C: float (1)> str ('a')> str ('1')
A == C: float (1)> str ('A')> str ('1')
A == C: str ('a')> str ('1')> int (0)
A == C: str ('a')> str ('1')> float (0)
A == C: str ('')> float (-INF)> NULL (NULL)
A == C: str ('')> float (-INF)> bool (false)
A == C: str ('')> int (-1)> NULL (NULL)
A == C: str ('')> int (-1)> bool (false)
A == C: str ('')> float (-1)> NULL (NULL)
A == C: str ('')> float (-1)> bool (false)
A == C: array ()> float (NAN)> NULL (NULL)
A == C: array ()> float (NAN)> bool (false)
A == C: array ()> float (INF)> NULL (NULL)
A == C: array ()> float (INF)> bool (false)
A == C: array ()> float (-INF)> NULL (NULL)
A == C: array ()> float (-INF)> bool (false)
A == C: array ()> str ('a')> NULL (NULL)
A == C: array ()> str ('a')> bool (false)
A == C: array ()> int (1)> NULL (NULL)
A == C: array ()> int (1)> bool (false)
A == C: array ()> float (1)> NULL (NULL)
A == C: array ()> float (1)> bool (false)
A == C: array ()> str ('1')> NULL (NULL)
A == C: array ()> str ('1')> bool (false)
A == C: array ()> str ('A')> NULL (NULL)
A == C: array ()> str ('A')> bool (false)
A == C: array ()> str ('0')> NULL (NULL)
A == C: array ()> int (-1)> NULL (NULL)
A == C: array ()> int (-1)> bool (false)
A == C: array ()> float (-1)> NULL (NULL)
A == C: array ()> float (-1)> bool (false)
A == C: str ('')> float (NAN)> bool (false)
A == C: str ('')> float (NAN)> NULL (NULL)
A == C: str ('A')> str ('1')> int (0)
A == C: str ('A')> str ('1')> float (0)
A == C: int (0)> float (-INF)> NULL (NULL)
A == C: int (0)> float (-INF)> bool (false)
A == C: int (0)> int (-1)> NULL (NULL)
A == C: int (0)> int (-1)> bool (false)
A == C: int (0)> float (-1)> NULL (NULL)
A == C: int (0)> float (-1)> bool (false)
A == C: str ('0')> float (NAN)> bool (false)
A == C: str ('0')> float (-INF)> bool (false)
A == C: str ('0')> int (-1)> bool (false)
A == C: str ('0')> float (-1)> bool (false)
A == C: float (0)> float (-INF)> NULL (NULL)
A == C: float (0)> float (-INF)> bool (false)
A == C: float (0)> int (-1)> NULL (NULL)
A == C: float (0)> int (-1)> bool (false)
A == C: float (0)> float (-1)> NULL (NULL)
A == C: float (0)> float (-1)> bool (false)
A === C: str ('0')> float (NAN)> str ('0')
A === C: str ('')> float (NAN)> str ('')
A === C: str ('a')> float (NAN)> str ('a')
A === C: str ('1')> float (NAN)> str ('1')
A === C: str ('A')> float (NAN)> str ('A')

Fun String Vergleich: 'Queen' >'King' >'Jack' >'Ace'

Schauen Sie sich auch die PHP-Typvergleichstabellen an, die Paare abdecken:

  • isset() und is_null()
  • if() und empty()
  • boolean ==vs.===

Überprüfen Sie die Unterschiede zwischen PHP-Versionen live unter. http://3v4l.org/MAfDu .

CSᵠ
quelle
26
+1 geschweige denn die scrollbaren "Tabellen" mit den festen Spaltenüberschriften - raffinierte Idee;)
hakre
Muss man beim Typgießen einen strengen Operator verwenden? Ich meine, Sie haben geschrieben, if ( (string)$a===(string)$b )aber ist das nicht genau das Gleiche wie if ( (string)$a==(string)$b )?
Voitcus
@ Voitcus ja für Typ-Cast (string)1==(string)'01'-> bool(true)und für Typ-Jonglieren (1 . '')=='01'-> bool(true)nicht genau das gleiche, als ===wenn Sie bool(false)auf beide Konten bekommen würden
CSᵠ
1
Ein Tipp: Oktalwerte werden nicht "bei Zuweisung konvertiert", sondern vom Compiler interpretiert, der ASCII in tatsächliche Binärzahlen umwandeln muss.
IMSoP
INFINITY is equal to INFINITY which is mathematically incorrect!ist eine ausgesprochen umstrittene Aussage. Beachten Sie auch, dass dies NaNkonventionell nicht größer, kleiner oder gleich irgendetwas in einer mir bekannten Programmiersprache ist.
Dave Random
22

Nach Ihrer Korrektur des zweiten Teils Ihrer Frage überlasse ich die Antwort auf diesen Teil den anderen. Ich möchte nur die überraschendsten Antwort auf den ersten Teil Ihrer Frage geben, das heißt, ob es sich um ein Beispiel für die <und >Betreiber intransitiv sein. Hier ist es.

Das sind alles true:

"10" < "1a"
"1a" < "2"
"10" > "2"

Wenn <transitiv wäre ( $a < $b$b < $c$a < $c), wäre die letzte Zeile

"10" < "2"

aber PHP versucht freundlich zu sein (?!) und Strings als Zahlen zu interpretieren, wann immer es möglich ist.

Es stellt sich heraus , dass aufgrund der oben intransitivity, sort()die Sortier können gleiche Elemente zu einer unterschiedlichen Reihenfolge auf ihre Eingabereihenfolge , abhängig, selbst wenn keine zwei Elemente sind== (und kein Element ist NAN). Ich habe dies in einem Kommentar zu sort () hervorgehoben , dessen Kern ist:

sort(array("10", "1a", "2" )) => array("10", "1a", "2" )
sort(array("10", "2",  "1a")) => array("1a", "2",  "10")
sort(array("1a", "10", "2" )) => array("2",  "10", "1a")
sort(array("1a", "2",  "10")) => array("1a", "2",  "10")
sort(array("2",  "10", "1a")) => array("2",  "10", "1a")
sort(array("2",  "1a", "10")) => array("10", "1a", "2" )
Walter Tross
quelle
1
Der vorherige Kommentar bezieht sich auf einen Teil der Antwort (bezogen auf den zweiten Teil der Frage), den ich inzwischen gelöscht habe
Walter Tross
Das wurde jetzt entfernt;) Und eine schöne neue sort()Tabelle, die auch für die praktischen Auswirkungen beim Schreiben des zugehörigen Blog-Beitrags The Greatest PHP Value ausgewählt wurde . Nochmals vielen Dank für Ihre Antwort.
hakre
Bedeutet das, dass man usortwann immer möglich verwenden sollte?
Voitcus
2
@ Voitcus: Ich denke du meinst usort($arr, 'strcmp'). Dies funktioniert (natürlich für Strings), ist aber am besten zu verwenden sort($arr, SORT_STRING).
Walter Tross
@ WalterTross Ich meine, verwenden Sie immer Ihre eigene Funktion (nicht nur für Zeichenfolgen), um sicherzustellen, dass es immer korrekt ist
Voitcus