Jörg: Wie treibe ich php dieses warning aus?

Hallo,

ich inkludiere eine Datei vomn vielen anderen Dateien aus.

Nun gibt es manchmal ein vorhandenes Array $myGET['bla'], das es ein ander mal nicht gibt.

Woraufhin php folgende zeile mit einem Warnig versieht:

if(!isset($_FILES['upload']['bla']) && $myGET['blub'] != 1) {
// do something
}

// PHP Warning:  Undefined variable $myGET in ... on line 705
// PHP Warning:  Trying to access array offset on value of type null in ... on line 705

Eine Änderung auf $myGET['blub'] ?? null != 1 brachte übrigens keinen Erfolg, die beiden Warnigs sind genau dieselben.

Was tun?

Jörg

  1. Hallo Jörg,

    Was tun?

    Lesen und nachdenken.

    Ich gebe zu, es ist von PHP nicht unbedingt intuitiv gelöst, ich hätte das nicht so gemacht. Aber in JavaScript und C# ist es genauso, von daher ist es immerhin konsistent. Es scheint wohl Gründe zu geben.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      Lesen und nachdenken.

      Ich gebe zu, es ist von PHP nicht unbedingt intuitiv gelöst, ich hätte das nicht so gemacht. Aber in JavaScript und C# ist es genauso, von daher ist es immerhin konsistent. Es scheint wohl Gründe zu geben.

      Wenn Du auf womögliche Klammersetzung hinaus willst, da habe ich auch schon nahezu alles durch, was geht.
      Hat aber nicht gefruchtet.

      Jörg

      1. Hallo Jörg,

        nahezu alles durch, was geht. Hat aber nicht gefruchtet.

        Das Schlüsselwort heißt wohl "nahezu". Die richtige Klammerung fehlt dann noch.

        Ich bin ja ein nachtragender Mensch. Ich trag Dir gerne deinen Denkprozess hinterher 😉

        Ich verstehe Dich so, dass Du ?? eingebaut und dies bekommen hast:

        if (!isset($_FILES['upload']['bla']) && $myGET['blub'] ?? null != 1)

        Schritt 1:

        • Welche Operatoren verwendest Du? (Tipp: es sind 4)
        • Na gut, eigentlich sind es 5, aber der Arrayzugriff [] steht bei PHP nicht in der Operatorentabelle und ist so hoch priorisiert, dass wir hier keine Probleme damit haben.
        • In welcher Reihenfolge sollen sie ausgeführt werden?

        Schritt 2: Ordne die verwendeten Operatoren nach ihrer Priorität. Verwende dafür den Link, den ich vorhin gepostet habe.

        Schritt 3: Führt die identifizierte Priorität zu der Ausführungsreihenfolge, die Du willst?

        Nein, tut sie nicht. Wie musst Du klammern, um die gewünschte Reihenfolge zu bekommen?

        Also - es ist lösbar. Ich hab's in einer PHP Sandbox nachgeprüft.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          erstmal danke für Deine Hilfe, hab ich noch gar nicht gesagt gehabt. 👍

          Das Schlüsselwort heißt wohl "nahezu". Die richtige Klammerung fehlt dann noch.

          Ok, Du meinst diese hier:

          if ((!isset($_FILES['upload']['bla'])) && (($myGET['blub'] ?? null) != 1))

          oder gekürzt dann auch:

          if (!isset($_FILES['upload']['bla']) && ($myGET['blub'] ?? null) != 1)

          Da ichs aber trotzdem noch nicht wirklich verstehe, gehe ich mal Deine Anleitung durch:

          Operatoren und gewünschte Reihenfolge:

          1. !
          2. &&
          3. ??
          4. !=

          Ausführungsreihenfolge nach Priorität:

          1. !
          2. &&
          3. !=
          4. ??

          Ist das so von Dir gedacht gewesen?

          Weil dann würde die erste Klammerung klar sein und ich hätte es doch verstanden. Das Einzige, was ich dann komisch finde, ist, dass auch die gekürzte Version funktioniert, obwohl doch das ! in der Priorität vor dem && steht?

          Jörg

          1. Hallo Jörg,

            Ausführungsreihenfolge nach Priorität:

            1. !
            2. &&
            3. !=
            4. ??

            Nein. Das ist sie nicht ganz. != hat eine höhere Priorität als &&, damit Du Ausdrücke schreiben kannst wie $a != 3 && b != 4, ohne klammern zu müssen.

            So rum ist es richtig:

            1. !
            2. !=
            3. &&
            4. ??

            Und ich schnuppere ein Mistverständnis bei Dir, denn Du schriebst:

            Das Einzige, was ich dann komisch finde, ist, dass auch die gekürzte Version funktioniert, obwohl doch das ! in der Priorität vor dem && steht?

            Das ! steht auf Rang 1. Und Rang 1 bedeutet: Höchster Rang. Wird zuerst ausgeführt.

            Das ?? ist am niedrigsten, deshalb wird das != hinter dem ?? null Part zuerst ausgeführt und damit sagst Du, dass TRUE einzusetzen ist, nämlich null != 1, wenn der Teil links vom ?? undefiniert ist. Das ist einer der Fehler gewesen.

            Und dann ist && ebenfalls höher als ??, deswegen wird der ganze Klumpatsch links vom ?? ausgeführt, bevor er sich das ?? anschaut. Er möchte also !isset($_POST...) && $myGET['blah'] bestimmen, bevor er sich dem ?? zuwendet, und deswegen mault er rum, dass er 'blah' in $myGET nicht findet.

            Du möchtest:

            1. isset aufrufen und das Ergebnis negieren (das !)
            2. $myGET['blah'] bestimmen und 1erhalten, wenn'blah'` nicht vorhanden ist (das ??)
            3. Testen, ob das Ergebnis von (2) ungleich 1 ist
            4. Die Ergebnisse von 1 und 3 mit && verknüpfen

            Das hast Du in deinem "du meinst diese hier" Beispiel sehr schön geklammert und danach auch sehr schön die Klammern, die wegen der Operatorenrangfolge unnötig sind, wieder entfernt.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf,

              So rum ist es richtig:

              1. !
              2. !=
              3. &&
              4. ??

              Stimmt, das habe ich mich "irgendwie nicht getraut" 🧐

              Und ich schnuppere ein Mistverständnis bei Dir, denn Du schriebst:

              Nein, jetzt nicht mehr, denn nach dieser Reihenfolge ist natürlich auch die gekürzte Version logisch.

              Das hast Du in deinem "du meinst diese hier" Beispiel sehr schön geklammert und danach auch sehr schön die Klammern, die wegen der Operatorenrangfolge unnötig sind, wieder entfernt.

              Ich habe bei mir im Quelltext jezt tatsächlich die erste Version (mit den vielen Klammern) stehen lassen, weil die in x Jahren dann auch noch etwas besser und klarer lesbar ist als die gekürzte Version. Habe mir aber sicherheitshalber nochmal einen Link auf diesen Thtread hier als Kommentar dahinter gesetzt. 😉

              Danke für Deine ausführliche Hilfe.

              Jörg

              1. Hallo Jörg,

                Thtread

                Ich stelle mir gerade einen Briten vor, der dieses Wort auszusprechen versucht.

                Und bin fest entschlossen, ihm dabei nicht gegenüber zu stehen! 😬💦😲

                Rolf

                --
                sumpsi - posui - obstruxi
          2. Hi,

            ($myGET['blub'] ?? null)
            

            Beschreibung von ?? lautet:

            falls der erste Operand des ?? null ist, nimm den zweiten Operanden, sonst den ersten.

            also ist das Konstrukt doch gleichbedeutend mit

            $myGET['blub']
            

            cu,
            Andreas a/k/a MudGuard

            1. Hallo MudGuard,

              aus Programmierersicht ja.

              Aber ohne ?? gips halt eine PHP Warning.

              Rolf

              --
              sumpsi - posui - obstruxi
  2. Lieber Jörg,

    ich inkludiere eine Datei vomn vielen anderen Dateien aus.

    das bedeutet, dass diese Datei für sich alleine funktionieren muss. Wenn sie von anderen Dateien abhängig ist, dann muss dafür gesorgt werden, dass diese Abhängigkeiten auch erfüllt sind.

    Nun gibt es manchmal ein vorhandenes Array $myGET['bla'], das es ein ander mal nicht gibt.

    Diese Abhängigkeit solltest Du tunlichst anders lösen!

    In Deinem Fall würde ich die Bedingung anpassen:

    if(!isset($_FILES['upload']['bla']) && $myGET['blub'] != 1) {
    // do something
    }
    
    if(!array_key_exists('bla', $_FILES['upload'])
      && (
        !isset($myGET)
        || !array_key_exists('blub', $myGET)
        || $myGET['blub'] != 1
      )
    ) {
     // do something
    }
    

    Das ist echt von hinten durch die Brust ins Auge... aber eignet sich vielleicht als quick fix...

    Liebe Grüße

    Felix Riesterer

  3. Meintest Du etwa …

    if(
    		( ! isset( $_FILES['upload']['bla'] ) )
    	&&	(
    			( ! empty( $myGET['blub'] ) )
    		&&	myGET['blub'] != 1
    	)
    ) {
    // do something
    }
    

    ?

    Setze, um Dir „das Hirn nicht selbst wegzuhauen“ die Zeilenumbrüche bei runden Klammern so, wie Du das bei geschweiften (hoffentlich) auch machst. Klammern schaden auch dann nicht, wenn man sie weglassen könnte.

    Die Einrückungsebenen zeigen Dir, wo entlang Du das denken sollst.