Marktplatz - Eine große Auswahl an neuen und hilfreichen Modulen sowie modernen Templates für die modified eCommerce Shopsoftware
Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: Seltsames PHP-Problem bzgl. typen-sicherem Vergleich

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.990
    • Geschlecht:
    Hi Community.
    Lasst euch von Titel des Threads nicht abschrecken. Es geht im Grunde um ein einfach zu verstehendes Thema.
    Allerdings habe ich etwas erlebt/entdeckt was mich verwirrt zurücklässt.
    Stellt euch ein Array vor:
    Array (
      [0] => Array(
        [id] => 1
        [model] => test1
        [price] => 99
        [qty] => 1
       )
      [1] => Array(
        [id] => 2
        [model] => test2
        [price] => 129.99
        [qty] => 1
       )
      [sum_price] => 228.99
    )

    Der aufmerksame Leser hat sicherlich bemerkt, daß ein key, entgegen der anderen, nicht numerisch ist, nämlich sum_price. So weit so gut.
    Nun möchte ich durch das Array loopen und mir die Werte ausgeben lassen, außer dem Wert in sum_price, den will ich getrennt ausgeben.
    Ich mache also vereinfacht Folgendes:
    Code: PHP  [Auswählen]
    foreach($array as $k => $vals) {
      if($k != 'sum_price') {
        echo $vals['id'].' | '.$vals['model'].' | '.$vals['price'].' | '.$vals['qty'].'<br />;
      }
    }

    Auf PHP 8.1 läuft das wie erwartet.
    Auf PHP 7.3.4 jedoch nicht. Da wird im foreach  nichts ausgegeben.
    Hat mich bestimmt 'ne halbe Stunde oder gar mehr gekostet um herauszufinden was hier gebacken ist.
    Der Code ist etwas komplexer als das vereinfachte Beispiel hier, mit vorausgehenden If-Conditions.
    Auf PHP 7.3.4 läuft es nur wenn der Vergleich typen-sicher gemacht wird ( !== anstatt !=), also so:
    Code: PHP  [Auswählen]
    foreach($array as $k => $vals) {
      if($k !== 'sum_price') {
        echo $vals['id'].' | '.$vals['model'].' | '.$vals['price'].' | '.$vals['qty'].'<br />;
      }
    }

    Was ist denn da los. Habe ich noch nie gehört oder gesehen.
    PHP ist, was allenthalben immer mal wieder kritisiert wird, sehr typen-tolerant.
    Will sagen
    Code: PHP  [Auswählen]
    $my_var = 1;
    var_dump($my_var == '1');

    $my_other_var = '1';
    var_dump($my_var == 1);

    ergibt beides bool(true), was mit === nicht so wäre.

    Was ist denn dann auf PHP 7.3.4 plötzlich los ?
    Hat jemand so etwas schonmal gehört oder erlebt ?
    Hat jemand Insider-Wissen und kann mich aufklären ?

    Gruß,
    noRiddle

    Linkback: https://www.modified-shop.org/forum/index.php?topic=42591.0

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.990
    • Geschlecht:
    Re: Seltsames PHP-Problem bzgl. typen-sicherem Vergleich
    Antwort #1 am: 05. Oktober 2022, 04:42:42
    Das Beispiel mit der Typen-Toleranz muß natürlich so lauten:
    Code: PHP  [Auswählen]
    $my_var = 1;
    var_dump($my_var == '1');

    $my_other_var = '1';
    var_dump($my_other_var == 1);

    Beim 2. var_dump()  hatte ich mich verschrieben.
    Die Aussage zu dem Beispiel bleibt.

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.879
    Re: Seltsames PHP-Problem bzgl. typen-sicherem Vergleich
    Antwort #2 am: 05. Oktober 2022, 12:43:18
    Hallo noRiddle,
    war auch von diesem Verhalten überrascht.

    Die Erklärung findest du bei php.net, wenn du etwas nach unten scrollst kommt der rote Abschnitt "Warnung vor PHP 8.0.0 ...".

    Die Zeichenkette 'sum_price' wird vor PHP8  in die Zahl 0 gewandelt und erst dann mit dem Key 0 verglichen.

    Gruß Karl

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.990
    • Geschlecht:
    Re: Seltsames PHP-Problem bzgl. typen-sicherem Vergleich
    Antwort #3 am: 05. Oktober 2022, 13:12:21
    Danke für die Information, das hatte ich gar nicht gesehen, als ich auf dieser Doku-Seite mit den Vergleichs-Operatoren geschaut habe.
    Ich habe das Problem auch nicht richtig dargestellt.
    Ich schrieb es würde im foreach  nichts ausgegeben auf PHP 7.4.3. Es wird jedoch lediglich der erste Wert nicht ausgegeben, also der mit dem Key 0, was zu der von dir verlinkten Darstellung passt, aber zu verstehen ist es nicht so einfach.
    In der Doku heißt es ja
    Zitat
    Vor PHP 8.0.0 wurde bei einem Vergleich einer Zeichenkette mit einer Zahl oder einer numerischen Zeichenkette die Zeichenkette vor dem Vergleich in eine Zahl umgewandelt und der Vergleich numerisch durchgeführt.
    Da muß man erst einmal wissen, daß die Umwandlung eines Strings der im String keine Zahl enthält zu 0 wird, denn ansonsten dürften auch die anderen Werte die einen numerischen Key haben nicht ausgegeben werden.

    So ist das Szenario nachstellbar:
    Code: PHP  [Auswählen]
    $my_arr = array(0 => array('id' => 1,
                               'model' => 'test1',
                               'price' => 99,
                               'qty' => 1
                              ),
                    1 => array('id' => 2,
                               'model' => 'test2',
                               'price' => 129.99,
                               'qty' => 1
                              ),
                    2 => array('id' => 3,
                               'model' => 'test3',
                               'price' => 149.99,
                               'qty' => 1
                              ),
                    3 => array('id' => 4,
                               'model' => 'test4',
                               'price' => 49,
                               'qty' => 1
                              ),
                   'sum_price' => 427.98
    );

    foreach($my_arr as $k => $vals) {
      if($k != 'sum_price') {
        echo $vals['id'].' | '.$vals['model'].' | '.$vals['price'].' | '.$vals['qty'].'<br />';
      }
    }

    Ich frage mich gerade wie man den modified-Code mal durchscannen könnte, ob es da Vorkommen solcher Szenarien gibt. Da sollte man dann sicherheitshalber den typen-sicheren Vergleichsoperator verwenden.

    Vielen Dank nochmals.

    Gruß,
    noRiddle
    Trade Republic - Provisionsfrei Aktien handeln
    0 Antworten
    1856 Aufrufe
    30. Juli 2012, 13:34:56 von PeterRingler
    2 Antworten
    2780 Aufrufe
    17. Juli 2011, 17:30:37 von nighthawk.84
    12 Antworten
    7439 Aufrufe
    02. März 2011, 16:03:40 von Tomcraft
    5 Antworten
    1499 Aufrufe
    15. August 2019, 11:24:35 von Q