Jonglerie de type et comparaisons (strictes) supérieures / inférieures à PHP

115

PHP est célèbre pour son jonglage de types. Je dois admettre que cela me laisse perplexe, et j'ai du mal à trouver des éléments logiques / fondamentaux de base dans les comparaisons.

Par exemple: si $a > $best vrai et $b > $cest vrai, cela signifie-t-il que $a > $cc'est toujours vrai aussi?

En suivant une logique de base, je dirais oui, mais je suis perplexe, je ne fais pas vraiment confiance à PHP. Peut-être que quelqu'un peut donner un exemple où ce n'est pas le cas?

De plus, je me demande avec les opérateurs stricts inférieurs à et stricts supérieurs à (car leur signification est décrite comme strictement que je ne connaissais que dans le passé grâce aux comparaisons d'égalité) si cela fait une différence si les opérandes gauche et droit sont échangés avec valeurs strictement inégales:

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

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

Pour la plupart de toutes les combinaisons de comparaison de types, ces opérateurs de comparaison plus grands / plus petits ne sont pas documentés, la lecture du manuel n'a donc pas été vraiment utile dans ce cas.

hakre
la source
Je suppose que vous voulez corriger cette ligne ($a > $b) !== ($b < $a)?
Walter Tross
ah, ok, alors j'ai mal compris cela. Devra fixer ma réponse en conséquence. Drôle tous ces gens qui écrivent des traités au lieu de réponses et ne lisent pas attentivement votre question ...
Walter Tross

Réponses:

208

Les opérateurs de comparaison PHP s'écartent des définitions informatiques et scientifiques de plusieurs manières:

Pour constituer une relation d'équivalence == doit être réflexive, symétrique et transitive:

  • L' ==opérateur PHP n'est pas réflexif , c'est $a == $a-à- dire n'est pas toujours vrai:

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

    Remarque: le fait que toute comparaison impliquant NANsoit toujours falsen'est pas spécifique à PHP. Il est mandaté par la norme IEEE 754 pour l'arithmétique à virgule flottante ( plus d'informations ).

  • L' ==opérateur PHP est symétrique , c'est $a == $b-à- dire et $b == $aest toujours le même.

  • L' ==opérateur PHP n'est pas transitif , c'est-à-dire de $a == $bet $b == $cne suit pas$a == $c :

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

Pour constituer un ordre partiel <= / >=doit être réflexif, antisymétrique et transitif:

  • L' <=opérateur PHP n'est pas réflexif , c'est-à $a <= $a- dire n'est pas toujours vrai (exemple identique à pour ==).

  • L' <=opérateur PHP n'est pas anti-symétrique , c'est-à-dire de $a <= $bet $b <= $ane suit pas $a == $b:

    var_dump(NAN <= "foo"); // bool(true)
    var_dump("foo" <= NAN); // bool(true)
    var_dump(NAN == "foo"); // bool(false)
  • L' <=opérateur PHP n'est pas transitif , c'est-à-dire from $a <= $bet $b <= $cne suit pas $a <= $c(exemple identique à pour ==).

  • Extra: l' <=opérateur PHP n'est pas total , c'est à dire les deux $a <= $bet $b <= $apeut être faux:

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

Pour constituer un ordre partiel strict < / >doit être irréflexif, asymétrique et transitif:

  • L' <opérateur PHP est irréfléchi , c'est $a < $a-à- dire qu'il n'est jamais vrai. Notez que cela n'est vrai qu'à partir de PHP 5.4 . Auparavant INF < INFévalué à true.

  • L' <opérateur PHP n'est pas asymétrique , c'est-à-dire que from $a < $bne suit pas !($b < $a)(Exemple identique à celui de <=ne pas être anti-symétrique).

  • L' <opérateur PHP n'est pas transitif , c'est-à-dire de $a < $bet $b < $cne suit pas $a < $c:

    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)
  • Extra: l' <opérateur PHP n'est pas trichotomique , c'est-à-dire tout de $a < $b, $b < $aet $a == $bpeut être faux (Exemple identique à celui de <=ne pas être total).

  • Extra: l' <opérateur PHP peut être circulaire , c'est-à-dire qu'il est possible que $a < $b, $b < $cet $c < $a:

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

    Remarque: L'exemple ci-dessus lance un avis «L'objet de la classe stdClass n'a pas pu être converti en double».

Vous pouvez trouver quelques bons graphiques pour les opérateurs de comparaison PHP sur PHP Sadness 52 - Opérateurs de comparaison .

En dernière note, je tiens à souligner qu'il ya deux égalités que PHP ne garantie (contrairement à à peu près tout le reste). Ces deux sont toujours valables, simplement parce que le compilateur réduit l'un à l'autre:

($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)
NikiC
la source
2
Wow, belle réponse. Il n'est donc pas possible de formuler des expressions logiques avec PHP comme ($a > $b) and ($b > $c)avec $a > $cmême si la documentation dit que ces </ >opérateurs disent qu'ils sont stricts ?
hakre
26
Les opérateurs IMHO suivent les règles mathématiques, mais uniquement lorsqu'ils traitent les mêmes types de données. Le casting de type est ce qui crée vraiment la confusion ici (et dans de nombreuses autres situations). Lorsque vous comparez des nombres et des chaînes et que les conversions de types de valeurs spéciales sont effectuées avant les opérateurs, les opérateurs de comparaison à proprement parler ne sont donc pas déroutants, le casting est ...
ivanhoe
6
@ ivanhoe011 La vérité est que les deux sont :) Les règles de comparaison PHP et les règles de casting PHP diffèrent , vous ne pouvez pas simplement dire que $a == $bc'est la même chose que (type) $a === (type) $b. Un exemple simple de ceci est que "15" == "0xf", mais (int) "15" !== (int) "0xf". Et les règles de comparaison et de casting en PHP sont totalement folles ^^
NikiC
3
@NikiC: (int)"0xf"évalue en entier 0, donc bien sûr 0 !== 15. La comparaison dans cet exemple se comporte exactement comme prévu. C'est le casting qui est déroutant ici. J'admets que (INF < INF) === truec'était un véritable problème de comparaison, mais c'était un cas particulier et il a été résolu comme vous l'avez souligné.
Bonne
1
Je ne blâme pas nécessairement les concepteurs de PHP pour certaines des décisions qui avaient du sens à propos de la coercition de type à l'époque ... mais j'ai l'impression qu'ils auraient dû remarquer les résultats de ces choix de conception et réaliser immédiatement que les choix étaient manifestement faux. L'exemple le plus évident est le commentaire de @ ravz.
Tchad
88

Il n'y a pas d' opérateurs de comparaison strictement identiques ( >==ou <==) en PHP (par PHP 5.6.14 au moins) , mais il existe plusieurs façons d' imposer une vérification de type stricte avant de vérifier Greater / Lower:

  1. Vérifiez les deux types de variables avec if (gettype($a) === gettype($b))
  2. Forcez votre type de fonte nécessaire, par exemple. if ((string)$a === (string)$b)
  3. Forcez votre jongle de type nécessaire, par exemple. if (($a . '') === ($b . ''))

Prenez note que:

  • La précision en virgule flottante est limitée
  • INFet NANsont de type floatsous
  • Certains Infinity équivalent à d'autres Infinity (depuis PHP 5.4)
  • La notation scientifique eest toujours de type float, et jamais integermême si le nombre est petit
  • Les entiers qui dépassent PHP_INT_MAXsont automatiquement convertis enfloat
  • Les flottants au-dessus des limites du système obtiennent la INFvaleur
  • Les variables non définies sont de type et de valeur NULL
  • Les entiers précédés de 0sont convertis d'octal en décimal (par convention)
  • La conversion de chaînes contenant un entier avec un début 0 en entier supprime le début0

Liste de quelques comparaisons exotiques:

Très étrange:
     $ un 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) false false false false false false
  float (NAN) float (INF) false false false false false false
  float (NAN) float (NAN) false false false false false false
  float (NAN) int (-1) false false false false false false
  float (NAN) int (0) false false false false false false
  float (NAN) int (1) faux faux faux faux faux faux

Égal mais pas identique:

     $ un 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) faux faux vrai vrai vrai faux
  NULL (NULL) str ('') faux faux vrai vrai vrai faux
   array () bool (false) false false 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 (vrai) faux faux vrai vrai vrai faux
  bool (vrai) float (1) faux faux vrai vrai vrai faux
  float (INF) bool (vrai) faux faux vrai vrai vrai faux
  float (NAN) bool (vrai) faux faux vrai vrai vrai faux
  bool (vrai) int (-1) faux faux vrai vrai vrai faux
  bool (vrai) int (1) faux faux vrai vrai vrai faux
  bool (true) str ("\ 0") false false true true true false
  bool (vrai) str ('+') faux faux vrai vrai vrai faux
  bool (vrai) str ('-') faux faux vrai vrai vrai faux
  bool (vrai) str ('01 ') faux faux vrai vrai vrai faux
  bool (vrai) str ('1') faux faux vrai vrai vrai faux
  bool (true) str ('false') false false true true true false
 str ('text') bool (vrai) faux faux vrai vrai vrai faux
 str ('vrai') bool (vrai) faux faux vrai vrai vrai faux
    int (0) float (0) faux faux vrai vrai vrai faux
  str ("\ 0") float (0) false false true true true false
   str ('') float (0) faux faux vrai vrai vrai faux
   str ('+') float (0) faux faux vrai vrai vrai faux
   str ('-') float (0) faux faux vrai vrai vrai faux
   str ('0') float (0) faux faux vrai vrai vrai faux
 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) faux faux vrai vrai vrai faux
   float (1) str ('01 ') faux faux vrai vrai vrai faux
   float (1) str ('1') faux faux vrai vrai vrai faux
  str ("\ 0") int (0) faux faux vrai vrai vrai faux
   str ('') int (0) faux faux vrai vrai vrai faux
   str ('+') int (0) faux faux vrai vrai vrai faux
   str ('-') int (0) faux faux vrai vrai vrai faux
    int (0) str ('0') faux faux vrai vrai vrai faux
 str ('false') int (0) false false true true true false
 str ('text') int (0) faux faux vrai vrai vrai faux
 str ('vrai') int (0) faux faux vrai vrai vrai faux
    int (1) str ('01 ') faux faux vrai vrai vrai faux
    int (1) str ('1') faux faux vrai vrai vrai faux
   str ('1') str ('01 ') faux faux vrai vrai vrai faux

Plus bas et plus grand en même temps?

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

Égal ET identique:

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

Inférieur ou supérieur:

     $ un VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) bool (vrai) faux vrai vrai faux faux faux
 float (-INF) NULL (NULL) vrai faux faux vrai faux faux
  NULL (NULL) float (1) faux vrai vrai faux faux faux
  float (INF) NULL (NULL) vrai faux faux vrai faux faux
  float (NAN) NULL (NULL) vrai faux faux vrai faux faux
  NULL (NULL) int (-1) faux vrai vrai faux faux faux
  NULL (NULL) int (1) faux vrai vrai faux faux faux
  NULL (NULL) str ("\ 0") false true true false false false
  NULL (NULL) str ('+') faux vrai vrai faux faux faux
  NULL (NULL) str ('-') faux vrai vrai faux faux faux
  NULL (NULL) str ('0') faux vrai vrai faux faux faux
  NULL (NULL) str ('01 ') faux vrai vrai faux faux faux
  NULL (NULL) str ('1') faux vrai vrai faux faux faux
  NULL (NULL) str ('false') false true true false false false
  NULL (NULL) str ('texte') faux vrai vrai faux faux faux
  NULL (NULL) str ('vrai') faux vrai vrai faux faux faux
   array () bool (vrai) faux vrai vrai faux faux faux
 float (-INF) array () faux vrai vrai faux faux faux
   array () float (0) vrai faux faux vrai faux faux
   array () float (1) vrai faux faux vrai faux faux
  float (INF) array () faux vrai vrai faux faux faux
  float (NAN) array () false true true false false false
   array () int (-1) vrai faux faux vrai faux faux
   array () int (0) vrai faux faux vrai faux faux
   array () int (1) vrai faux faux vrai faux faux
   array () str ("\ 0") vrai faux faux vrai faux faux
   str ('') array () faux vrai vrai faux faux faux
   array () str ('+') vrai faux faux vrai faux faux
   array () str ('-') vrai faux faux vrai faux faux
   array () str ('0') vrai faux faux vrai faux faux
   array () str ('01 ') vrai faux faux vrai faux faux
   array () str ('1') vrai faux faux vrai faux faux
   array () str ('false') true false false true false false
   array () str ('text') vrai faux faux vrai faux faux
   array () str ('vrai') vrai faux faux vrai faux faux
  bool (true) bool (false) true false false true false false
 float (-INF) bool (false) true false false true false false
   float (1) bool (false) true false false true false false
  float (INF) bool (false) true false false true false false
  float (NAN) bool (false) true false false true false false
 bool (false) int (-1) false true true false false false
    int (1) bool (faux) vrai faux faux vrai faux faux
 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) true false false true false false
 bool (false) str ('false') false true true false false false
 str ('text') bool (false) true false false true false false
 str ('true') bool (false) true false false true false false
  bool (vrai) float (0) vrai faux faux vrai faux faux
  bool (vrai) int (0) vrai faux faux vrai faux faux
   str ('') bool (vrai) faux vrai vrai faux faux faux
  bool (vrai) str ('0') vrai faux faux vrai faux faux
 float (-INF) float (0) faux vrai vrai faux faux faux
 float (-INF) float (1) faux vrai vrai faux faux faux
  float (INF) float (-INF) true false false true false false
 float (-INF) int (-1) faux vrai vrai faux faux faux
 float (-INF) int (0) faux vrai vrai faux faux faux
 float (-INF) int (1) faux vrai vrai faux faux faux
 float (-INF) str ("\ 0") false true true false false false
 float (-INF) str ('') faux vrai vrai faux faux faux
 float (-INF) str ('+') faux vrai vrai faux faux faux
 float (-INF) str ('-') faux vrai vrai faux faux faux
 float (-INF) str ('0') faux vrai vrai faux faux faux
 float (-INF) str ('01 ') faux vrai vrai faux faux faux
 float (-INF) str ('1') faux vrai vrai faux faux faux
 float (-INF) str ('false') false true true false false false
 float (-INF) str ('texte') faux vrai vrai faux faux faux
 float (-INF) str ('vrai') faux vrai vrai faux faux faux
   float (1) float (0) vrai faux faux vrai faux faux
  float (INF) float (0) vrai faux faux vrai faux faux
   float (0) int (-1) vrai faux faux vrai faux faux
    int (1) float (0) vrai faux faux vrai faux faux
   float (0) str ('01 ') faux vrai vrai faux faux faux
   str ('1') float (0) vrai faux faux vrai faux faux
  float (INF) float (1) vrai faux faux vrai faux faux
   float (1) int (-1) vrai faux faux vrai faux faux
   float (1) int (0) vrai faux faux vrai faux faux
   float (1) str ("\ 0") vrai faux faux vrai faux faux
   str ('') float (1) faux vrai vrai faux faux faux
   float (1) str ('+') vrai faux faux vrai faux faux
   float (1) str ('-') vrai faux faux vrai faux faux
   float (1) str ('0') vrai faux faux vrai faux faux
   float (1) str ('false') true false false true false false
 str ('text') float (1) faux vrai vrai faux faux faux
 str ('vrai') float (1) faux vrai vrai faux faux faux
  float (INF) int (-1) vrai faux faux vrai faux faux
  float (INF) int (0) vrai faux faux vrai faux faux
  float (INF) int (1) vrai faux faux vrai faux faux
  float (INF) str ("\ 0") true false false true false false
  float (INF) str ('') vrai faux faux vrai faux faux
  float (INF) str ('+') vrai faux faux vrai faux faux
  float (INF) str ('-') vrai faux faux vrai faux faux
  float (INF) str ('0') vrai faux faux vrai faux faux
  float (INF) str ('01 ') vrai faux faux vrai faux faux
  float (INF) str ('1') vrai faux faux vrai faux faux
  float (INF) str ('false') true false false true false false
  float (INF) str ('texte') vrai faux faux vrai faux faux
  float (INF) str ('vrai') vrai faux faux vrai faux faux
    int (0) int (-1) vrai faux faux vrai faux faux
    int (1) int (-1) vrai faux faux vrai faux faux
  str ("\ 0") int (-1) vrai faux faux vrai faux faux
   str ('') int (-1) vrai faux faux vrai faux faux
   str ('+') int (-1) vrai faux faux vrai faux faux
   str ('-') int (-1) vrai faux faux vrai faux faux
   str ('0') int (-1) vrai faux faux vrai faux faux
   int (-1) str ('01 ') faux vrai vrai faux faux faux
   str ('1') int (-1) vrai faux faux vrai faux faux
 str ('false') int (-1) vrai faux faux vrai faux faux
 str ('text') int (-1) vrai faux faux vrai faux faux
 str ('vrai') int (-1) vrai faux faux vrai faux faux
    int (1) int (0) vrai faux faux vrai faux faux
    int (0) str ('01 ') faux vrai vrai faux faux faux
   str ('1') int (0) vrai faux faux vrai faux faux
    int (1) str ("\ 0") vrai faux faux vrai faux faux
   str ('') int (1) faux vrai vrai faux faux faux
    int (1) str ('+') vrai faux faux vrai faux faux
    int (1) str ('-') vrai faux faux vrai faux faux
    int (1) str ('0') vrai faux faux vrai faux faux
    int (1) str ('faux') vrai faux faux vrai faux faux
 str ('text') int (1) faux vrai vrai faux faux faux
 str ('vrai') int (1) faux vrai vrai faux faux faux
   str ('') str ("\ 0") faux vrai vrai faux faux faux
   str ('+') str ("\ 0") vrai faux faux vrai faux faux
   str ('-') str ("\ 0") vrai faux faux vrai faux faux
  str ("\ 0") str ('0') faux vrai vrai faux faux faux
  str ("\ 0") str ('01 ') faux vrai vrai faux faux faux
   str ('1') str ("\ 0") vrai faux faux vrai faux faux
 str ('false') str ("\ 0") true false false true false false
 str ('text') str ("\ 0") vrai faux faux vrai faux faux
 str ('true') str ("\ 0") true false false true false false
   str ('') str ('+') faux vrai vrai faux faux faux
   str ('') str ('-') faux vrai vrai faux faux faux
   str ('') str ('0') faux vrai vrai faux faux faux
   str ('') str ('01 ') faux vrai vrai faux faux faux
   str ('') str ('1') faux vrai vrai faux faux faux
   str ('') str ('false') faux vrai vrai faux faux faux
   str ('') str ('text') faux vrai vrai faux faux faux
   str ('') str ('vrai') faux vrai vrai faux faux faux
   str ('-') str ('+') vrai faux faux vrai faux faux
   str ('+') str ('0') faux vrai vrai faux faux faux
   str ('+') str ('01 ') faux vrai vrai faux faux faux
   str ('1') str ('+') vrai faux faux vrai faux faux
 str ('false') str ('+') vrai faux faux vrai faux faux
 str ('texte') str ('+') vrai faux faux vrai faux faux
 str ('vrai') str ('+') vrai faux faux vrai faux faux
   str ('-') str ('0') faux vrai vrai faux faux faux
   str ('-') str ('01 ') faux vrai vrai faux faux faux
   str ('1') str ('-') vrai faux faux vrai faux faux
 str ('false') str ('-') vrai faux faux vrai faux faux
 str ('texte') str ('-') vrai faux faux vrai faux faux
 str ('vrai') str ('-') vrai faux faux vrai faux faux
   str ('0') str ('01 ') faux vrai vrai faux faux faux
   str ('1') str ('0') vrai faux faux vrai faux faux
 str ('false') str ('0') true false false true false false
 str ('texte') str ('0') vrai faux faux vrai faux faux
 str ('vrai') str ('0') vrai faux faux vrai faux faux
 str ('false') str ('01 ') vrai faux faux vrai faux faux
 str ('text') str ('01 ') vrai faux faux vrai faux faux
 str ('vrai') str ('01 ') vrai faux faux vrai faux faux
   str ('1') str ('false') false true true false false false
 str ('texte') str ('1') vrai faux faux vrai faux faux
 str ('vrai') str ('1') vrai faux faux vrai faux faux
 str ('text') str ('false') true false false true false false
 str ('vrai') str ('faux') vrai faux faux vrai faux faux
 str ('vrai') str ('texte') vrai faux faux vrai faux faux

$a > $b > $cÉnigme quand: $an'est pas supérieur à $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 (vrai)> str ('')> float (NAN)
A == C: bool (vrai)> str ('')> float (-INF)
A == C: bool (vrai)> str ('')> int (-1)
A == C: bool (vrai)> str ('')> float (-1)
A == C: bool (vrai)> array ()> float (NAN)
A == C: bool (true)> array ()> float (INF)
A == C: bool (true)> array ()> float (-INF)
A == C: bool (vrai)> array ()> str ('a')
A == C: bool (vrai)> tableau ()> int (1)
A == C: bool (vrai)> array ()> float (1)
A == C: bool (vrai)> array ()> str ('1')
A == C: bool (vrai)> tableau ()> str ('A')
A == C: bool (vrai)> tableau ()> int (-1)
A == C: bool (vrai)> array ()> float (-1)
A == C: bool (vrai)> int (0)> float (-INF)
A == C: bool (vrai)> int (0)> int (-1)
A == C: bool (vrai)> int (0)> float (-1)
A == C: bool (vrai)> str ('0')> float (NAN)
A == C: bool (vrai)> str ('0')> float (-INF)
A == C: bool (vrai)> str ('0')> int (-1)
A == C: bool (vrai)> str ('0')> float (-1)
A == C: bool (true)> float (0)> float (-INF)
A == C: bool (vrai)> float (0)> int (-1)
A == C: bool (vrai)> 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 (faux)
A == C: str ('')> int (-1)> NULL (NULL)
A == C: str ('')> int (-1)> bool (faux)
A == C: str ('')> float (-1)> NULL (NULL)
A == C: str ('')> float (-1)> bool (faux)
A == C: array ()> float (NAN)> NULL (NULL)
A == C: array ()> float (NAN)> bool (faux)
A == C: array ()> float (INF)> NULL (NULL)
A == C: array ()> float (INF)> bool (faux)
A == C: tableau ()> float (-INF)> NULL (NULL)
A == C: tableau ()> float (-INF)> bool (faux)
A == C: array ()> str ('a')> NULL (NULL)
A == C: array ()> str ('a')> bool (faux)
A == C: tableau ()> int (1)> NULL (NULL)
A == C: tableau ()> int (1)> bool (faux)
A == C: tableau ()> float (1)> NULL (NULL)
A == C: array ()> float (1)> bool (faux)
A == C: tableau ()> str ('1')> NULL (NULL)
A == C: array ()> str ('1')> bool (faux)
A == C: tableau ()> str ('A')> NULL (NULL)
A == C: tableau ()> str ('A')> bool (faux)
A == C: array ()> str ('0')> NULL (NULL)
A == C: tableau ()> int (-1)> NULL (NULL)
A == C: tableau ()> int (-1)> bool (faux)
A == C: tableau ()> float (-1)> NULL (NULL)
A == C: array ()> float (-1)> bool (faux)
A == C: str ('')> float (NAN)> bool (faux)
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 (faux)
A == C: int (0)> int (-1)> NULL (NULL)
A == C: int (0)> int (-1)> bool (faux)
A == C: int (0)> float (-1)> NULL (NULL)
A == C: int (0)> float (-1)> bool (faux)
A == C: str ('0')> float (NAN)> bool (faux)
A == C: str ('0')> float (-INF)> bool (faux)
A == C: str ('0')> int (-1)> bool (faux)
A == C: str ('0')> float (-1)> bool (faux)
A == C: float (0)> float (-INF)> NULL (NULL)
A == C: float (0)> float (-INF)> bool (faux)
A == C: float (0)> int (-1)> NULL (NULL)
A == C: float (0)> int (-1)> bool (faux)
A == C: float (0)> float (-1)> NULL (NULL)
A == C: float (0)> float (-1)> bool (faux)
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')

Comparaison de cordes amusante: 'Queen' >'King' >'Jack' >'Ace'

Consultez également les tableaux de comparaison des types PHP couvrant les paires:

  • isset() et is_null()
  • if() et empty()
  • booléen ==vs.===

Vérifiez les différences entre les versions de PHP en direct sur. http://3v4l.org/MAfDu .

CSᵠ
la source
26
+1 sans parler des "tableaux" déroulants avec les en-têtes à colonnes fixes - idée astucieuse;)
hakre
Doit-on utiliser un opérateur strict lors du casting de caractères? Je veux dire que vous avez écrit if ( (string)$a===(string)$b )mais n'est-ce pas exactement la même chose que if ( (string)$a==(string)$b )?
Voitcus
@Voitcus oui à la fois pour le type-cast (string)1==(string)'01'-> bool(true)et pour le type-jongle (1 . '')=='01'-> bool(true)pas exactement la même chose que ===lorsque vous auriez bool(false)sur les deux comptes
CS13
1
Un petit choix: les valeurs octales ne sont pas "converties lors de l'affectation", elles sont interprétées par le compilateur, qui doit transformer l'ASCII en nombres binaires réels.
IMSoP
INFINITY is equal to INFINITY which is mathematically incorrect!est une déclaration résolument discutable. Notez également que ce NaNn'est par convention pas supérieur, inférieur ou égal à tout ce qui est dans n'importe quel langage de programmation que je connais.
DaveRandom
22

Après avoir corrigé la deuxième partie de votre question, je laisse la réponse à cette partie aux autres. Je veux juste donner la réponse la plus surprenante à la première partie de votre question, c'est-à-dire s'il existe un exemple d' opérateurs <et >qui sont intransitifs. C'est ici.

Ce sont tous true:

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

Si <étaient transitifs ( $a < $b$b < $c$a < $c), la dernière ligne serait

"10" < "2"

mais PHP essaie d'être gentil (?!) et d'interpréter les chaînes comme des nombres chaque fois qu'il le peut.

Il s'avère que, en raison de l'intransitivité ci-dessus, sort()peut trier les mêmes éléments dans un ordre différent en fonction de leur ordre d'entrée, même s'il n'y a pas deux éléments== (et qu'aucun élément n'est NAN). Je l'ai souligné dans un commentaire à sort () , dont l'essence est:

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
la source
1
le commentaire précédent fait référence à une partie de la réponse (liée à la deuxième partie de la question) que j'ai supprimée entre
Walter Tross
Supprimé cela maintenant;) Et une belle nouvelle sort()table, l'a également choisie pour les implications pratiques lors de la rédaction du billet de blog connexe The Greatest PHP Value . Merci encore pour votre réponse.
hakre
Cela signifie-t-il qu'il faut utiliser usortautant que possible?
Voitcus
2
@Voitcus: Je suppose que vous voulez dire usort($arr, 'strcmp'). Cela fonctionne (pour les chaînes, bien sûr), mais il est préférable d'utiliser sort($arr, SORT_STRING).
Walter Tross
@WalterTross, je veux dire, utilisez toujours votre propre fonction (pas seulement pour les chaînes) pour vous assurer qu'elle est toujours correcte
Voitcus