Christian: Kurze isset()-Notwendigkeitsfrage

Hallo,

es geht darum, dass Variablen in meinem Skript manchmal einfach nicht vorhanden sind.

Bei if ($gibtsnet > 2) {...} wird mir lediglich "Notice: Undefined variable/index" mitgeteilt, aber bei foreach beispielsweise ist's ja ein bisschen was anderes, also bei foreach ($gibtsnet as ...){...} bekommt man eine Warnung: "Warning: Invalid argument supplied for foreach()".

(Aus welchen Gründen) Sollte ich foreach mit if (isset($gibtsnet)) {...} umschließen? Oder gar auch bei if?

Ach und noch ne Frage, die ich hier vielleicht auch mal eben unterbringen kann:

Was bedeutet zum Beispiel: if (!$bsp) {} ? Ist das nur für Vars des Typs Boolean gedacht, also als Kurzform von if ($bsp == true) oder vielleicht als Kurzform von !isset($bsp)? Oder ist das gar keine gültige Schreibweise?
Ich hatte das hier und da mal gelesen und wusste nichts anzufangen, weil ich das "!" sonst als Negierungszeichen ansehe, mir aber nicht klar ist, was eine negierte Variable für eine Bedingung darstellen soll.

Viele Grüße
Christian

  1. Moin!

    Bei if ($gibtsnet > 2) {...} wird mir lediglich "Notice: Undefined variable/index" mitgeteilt,

    Besser wäre zu prüfen, ob es das gibt und wenn diese Bedingung erfüllte wird weiter zu prüfen:

    if (isset($gibtsnet) && ($gibtsnet > 2)) {
       ...
    }

    das ersetzt:

    if (isset($gibtsnet)) {
        if ($gibtsnet > 2) {
            ...
        }
    }

    aber bei foreach beispielsweise ist's ja ein bisschen was anderes, also bei foreach ($gibtsnet as ...){...} bekommt man eine Warnung: "Warning: Invalid argument supplied for foreach()".

    (Aus welchen Gründen)

    Die Funktion erwartet ein Array und eine Variable. Die Warnstufe ist dehalb höher, als bei if $gibtsnet, weil das mit NULL oder als zahl 0 angenommen werden kann, auch wenn das unsauber ist.

    Sollte ich foreach mit if (isset($gibtsnet)) {...} umschließen?

    Siehe oben.

    Oder gar auch bei if?

    Siehe oben.

    Alternative:

    if (!isset($gibtsnet)) {
       # wenn nicht übergeben: mit default-Wert anlegen.
       $gibtsnet=0;
    }

    if (isset($arGibtsNet)) {
       # wenn nicht übergeben: als leeren-Array anlegen.
       $arGibtsNet=array();
    }

    Was bedeutet zum Beispiel: if (!$bsp) {} ? Ist das nur für Vars des Typs Boolean gedacht, also als Kurzform von if ($bsp == true) oder vielleicht als Kurzform von !isset($bsp)?

    Ersteres, wenn es richtig wäre:

    if (!$bsp) {
        # Wenn $bsp leer (NULL), falsch (false) oder 0 (Zahl 0) ist
        # Wenn $bsp leer (NULL), nicht wahr (true) oder 0 (Zahl 0) ist
        ...
    }

    Eine Bitte: Si einfache Sachverhalte wie den letzten findet man sehr schnell selbst durch einen Dreizeiler heraus. Nutze diese Möglichkeit, das geht schneller.

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
    1. Moin!

      Bevor "Twilo" kommt und rummeckert: da fehlt irgendwo eine Klammer ... ich weiss das schon. Mag er sie setzen.

      MFFG (Mit freundlich- friedfertigem Grinsen)

      fastix®

      --
      Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
    2. echo $begrüßung;

      [...] foreach ($gibtsnet as ...){...} [...]
      Die Funktion erwartet ein Array und eine Variable.

      foreach ist keine Funktion.

      Die Warnstufe ist dehalb höher, als bei if $gibtsnet, weil das mit NULL oder als zahl 0 angenommen werden kann, auch wenn das unsauber ist.

      Den Satz verstehe ich nicht. Genauer: den Teil ab weil.

      if (isset($arGibtsNet)) {
         # wenn nicht übergeben: als leeren-Array anlegen.

      (Da fehlt noch eine Negation.)

      Eine Bitte: Si einfache Sachverhalte wie den letzten findet man sehr schnell selbst durch einen Dreizeiler heraus. Nutze diese Möglichkeit, das geht schneller.

      Dem stimme ich zu. Selber machen (inklusive Erfahrung mit Fehlern sammeln) ist meist auch einprägsamer als erzählt bekommen.

      echo "$verabschiedung $name";

      1. Moin!

        Die Warnstufe ist dehalb höher, als bei if $gibtsnet, weil das mit NULL oder als zahl 0 angenommen werden kann, auch wenn das unsauber ist.

        Den Satz verstehe ich nicht. Genauer: den Teil ab weil.

        Ein
        <?
        error_reporting (1); # Abschalten aller nicht-fatalen Fehler
        echo (1*$gibtsnet);
        echo "<br>";
        echo ($gibtsnet==NULL) ? "NULL": "Nicht-NULL";
        echo "<br>";
        echo ($gibtsnet==$gibtnet) ? "leerer-String": "kein leerer String";
        echo "<br>";
        echo (1*$gibtsnet);
        ?>

        erklärt Dir das.

        (Da fehlt noch eine Negation.)

        Mist. Das sollte für den Twilo aufgehoben werden.

        MFFG (Mit freundlich- friedfertigem Grinsen)

        fastix®

        --
        Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
        1. Moin!

          echo ($gibtsnet==$gibtnet) ? "leerer-String": "kein leerer String";

          darf durch:

          echo ($gibtsnet=='') ? "leerer-String": "kein leerer String";

          ersetzt werden.

          MFFG (Mit freundlich- friedfertigem Grinsen)

          fastix®

          --
          Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
        2. echo $begrüßung;

          Die Warnstufe ist dehalb höher, als bei if $gibtsnet, weil das mit NULL oder als zahl 0 angenommen werden kann, auch wenn das unsauber ist.

          Den Satz verstehe ich nicht. Genauer: den Teil ab weil.

          Ein

          [...]

          erklärt Dir das.

          Nein, irgendwie nicht. Ich sehe den Zusammenhang mit foreach nicht. Wofür steht das "das" hinter dem "weil"? Was ist und warum unsauber?

          Mist. Das sollte für den Twilo aufgehoben werden.

          Sag mal, was ist denn los mit dir? Du bist in irgendwie so unleidlich in letzter Zeit. Ich versteh das ja, wenn man mal auf die Palme gebracht wird, weil man sich ungerecht behandelt fühlt, oder dies wurde. Aber so nachtragend muss man ja wohl nicht unbedingt sein. Es ist auch nicht nötig, den Frust im gesamten Forum zu verteilen.
          (Nein, ich erwarte keine Antwort auf diesen Teil. Es reicht mir, wenn ich dich (hoffentlich) ein wenig zum Nachdenken anregen konnte und du ein wenig gelassener wirst und vielleicht das eine oder andere Wort vor dem Absenden deiner Postings durch eine nettere Variante austauschst.)

          echo "$verabschiedung $name";

          1. Moin!

            Die Warnstufe ist dehalb höher, als bei if $gibtsnet, weil das mit NULL oder als zahl 0 angenommen werden kann, auch wenn das unsauber ist.

            Den Satz verstehe ich nicht. Genauer: den Teil ab weil.

            Ein
            [...]
            erklärt Dir das.

            Nein, irgendwie nicht. Ich sehe den Zusammenhang mit foreach nicht. Wofür steht das "das" hinter dem "weil"?

            Ganz einfach: Die einfache Variable $gibtsnet (bezeichnet als "das") wird, wenn sie nicht besetzt ist, in Operationen kontextabhängig als NULL, 0, '' (leerer String) oder false angenommen.

            Der Zusammenhang mit foreach ist ein negativer: Ein leerer Array wird eben nicht angenommen, darin besteht der Gegensatz und der Unterschied in der ausgelösten Warnstufe (Notice <-> Warning)

            Was ist und warum unsauber?

            Das ist ja wohl klar. Eine Variable, deren Herkunft (also Inhalt) ungeklärt ist verwendet man nicht einfach so. Das führt zumindest zu einer schlechteren Pflege des Codes. Stell dir vor, ein Programmierer braucht mal eben einen leeren String ('') und hat gerade nur eine Hand  frei (Fettbemme in der linken), will keine Umstände mit der Festelltaste haben, kann sich aber mittels Maus ein bis dato unbenutzes $str irgenwoher kopieren und benutzt es als leeren String in Zeile 14267 einer includierten Datei... später soll jemand dieses hübsche Skriptmonster verhübschen oder diesem Funktionen hinzufügen oder Disfunktionen reparieren.... viel Spaß!

            In Perl gibts zur Verhinderung derlei Murkses die Option -w (zu verwenden beim Aufruf oder in der shebang), in VBA gibts 'option explicit', in vielen anderen Programmiersprachen löst sowas stets eine zum Abbruch führende Exception aus.

            MFFG (Mit freundlich- friedfertigem Grinsen)

            fastix®

            --
            Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
            1. echo $begrüßung;

              Na bitte, du kannst es doch. So ist das doch schon viel verständlicher.

              Der Zusammenhang mit foreach ist ein negativer: Ein leerer Array wird eben nicht angenommen, darin besteht der Gegensatz und der Unterschied in der ausgelösten Warnstufe (Notice <-> Warning)

              Hier muss ich noch mal etwas korrigieren bzw. etwas genauer ausholen. Wenn auf eine bisher unbekannte Variable lesend zugegriffen wird, ergibt das den Wert ein NULL. Die Variable wird dabei noch nicht einmal angelegt, was ein

              error_reporting(E_ALL);
                var_dump($nix);
                var_dump($nix);

              mit einer zweifachen "Undefined variable"-Notice bestätigt. Noch eine Probe:

              $nix = NULL;
                var_dump($nix);

              Das erzeugt keine Notice.

              NULL wird bei einem expliziten (= extra verlangtem) Typecast in ein leeres Array gewandelt:

              var_dump((array)$nix); // Ausgabe: array(0) {}

              Alle anderen skalaren Typen (integer, string, ...) werden auch nur bei einem expliziten Typecast in ein Ein-Element-Array gewandelt. Implizite (= nicht extra verlagte, von PHP selbst ausgeführte) Skalar-zu-Array-Typecasts werden stets mit einer Warnung quittiert und nicht ausgeführt. Das ist bei foreach so und bei Funktionen, die ein Array als Parameter haben wollen, auch.

              var_dump($nix); // Ausgabe: NULL
                array_push($nix, 'foo');
                var_dump($nix); // Ausgabe: NULL

              $nix ist also kein Array geworden, das ein Element mit dem Wert 'foo' enthalten haben sollte.

              Für eine derartige "Arbeitsverweigerung" ist eine Warnung mehr als angebracht.

              Stell dir vor, ein Programmierer braucht mal eben einen leeren String ('') und hat gerade nur eine Hand  frei (Fettbemme in der linken), will keine Umstände mit der Festelltaste haben, kann sich aber mittels Maus ein bis dato unbenutzes $str irgenwoher kopieren und benutzt es als leeren String

              Du könntest Leute kennen... Ich würde denen nicht den "Titel" Programmierer geben.

              In Perl gibts zur Verhinderung derlei Murkses die Option -w [...]

              Und PHP ist wenigstens so freundlich, mindestens eine Notice zu erzeugen, wenn man diese durch ein E_ALL im error_reporting zulässt.

              in vielen anderen Programmiersprachen löst sowas stets eine zum Abbruch führende Exception aus.

              Bist du sicher, dass das auch für skalare Variablen so streng gehandhabt wird und nicht nur für nicht initialisierte Objekte, was zu einer Null-Pointer/Reference-Exception führt?

              echo "$verabschiedung $name";

              1. Moin!

                Bist du sicher, dass das auch für skalare Variablen so streng gehandhabt wird und nicht nur für nicht initialisierte Objekte, was zu einer Null-Pointer/Reference-Exception führt?

                Ja.

                MFFG (Mit freundlich- friedfertigem Grinsen)

                fastix®

                --
                Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
              2. Danke für die Antworten, ihr beiden!

                Grüße
                Christian

  2. echo $begrüßung;

    es geht darum, dass Variablen in meinem Skript manchmal einfach nicht vorhanden sind.

    Das ist sehr schlecht. Variablen sollte immer mit einem definierten Wert initialisiert werden. Wenn du es nicht machst, macht es vielleicht ein anderer, wenn register_globals eingeschaltet ist...

    [...] bei foreach ($gibtsnet as ...){...} bekommt man eine Warnung: "Warning: Invalid argument supplied for foreach()".

    (Aus welchen Gründen) Sollte ich foreach mit if (isset($gibtsnet)) {...} umschließen?

    foreach erwartet ein Array[*]. Mit allem anderen ist es kaum sinnvoll die Schleife auszuführen.

    Wenn dann also if (isset($var) and is_array($var)) foreach ($var...

    Ob es aber sinnvoll ist, die Schleife nicht auszuführen, oder vielleicht lieber die Reißleine zu ziehen (exit), musst du selbst entscheiden.

    Oder gar auch bei if?

    Das ist kontextabhängig und nicht pauschal beantwortbar.

    Ach und noch ne Frage, die ich hier vielleicht auch mal eben unterbringen kann:

    Was bedeutet zum Beispiel: if (!$bsp) {} ? Ist das nur für Vars des Typs Boolean gedacht, also als Kurzform von if ($bsp == true) oder vielleicht als Kurzform von !isset($bsp)? Oder ist das gar keine gültige Schreibweise?

    if ($bool == true) ist doppelt gemoppelt. Zuerst wird $bool (oder auch jeder beliebige andere Ausdruck) ausgewertet, ob es irgendwie, auch unter Einbeziehung der automatischen Typumwandlung, als einer der beiden boolschen Werte interpretiert werden kann. (Siehe Handbuch-Kapitel Booleans, unter Converting to boolean.) Dieses Ergebnis ist bereits true oder false. Das nochmal mit true oder false zu vergleichen um true oder false zu erhalten ist wenig sinnvoll.

    Es ist nur bei === sinnvoll, also wenn die Variable / der Ausdruck unbedingt vom Typ boolean sein muss, um nicht durch eine autom. Typumwandlung "geärgert" zu werden.
    Beispielsweise beim Ergebnis der Funktion strpos(): 0 kommt raus, wenn der gesuchte Teilstring am Anfang enthalten ist, aber false kommt raus, wenn er nicht drin ist.

    Ich hatte das hier und da mal gelesen und wusste nichts anzufangen, weil ich das "!" sonst als Negierungszeichen ansehe, mir aber nicht klar ist, was eine negierte Variable für eine Bedingung darstellen soll.

    Na das Gegenteil. Wenn in $var etwas, das true entspricht steht, ergibt !$var false, und umgekehrt.

    echo "$verabschiedung $name";

    [*] Ein Object wird durch die automatische Typumwandlung zu einem Array gecastet.