Linuchs: Wert geht verloren, wenn ein anderer Wert mit . angehängt wird

Moin,

wenn ich im Adressstamm zwei Ansprechpartner habe, möchte ich per PHP beiden eine Mail schicken:

echo "p591b: email=[".$row_vip['email']."]<br>";
echo "p591b: email_2=[".$row_vip['email_2']."]<br>";
  $mailEmail  = $row_vip['email']
              .( $row_vip['email_2'] && strpos( $row_vip['email_2'], "@" )) ? ",".$row_vip['email_2'] : '';
echo "p591b: mailEmail=[".$mailEmail."]<br>";

Anzeige:

p591b: email=[Jan@example.com]
p591b: email_2=[john@example.com]
p591b: mailEmail=[,john@example.com]

Was läuft falsch? Kann doch nur eine Kleinigkeit sein, die ich nicht sehe.

Gruß, Linuchs

  1. Hallo Linuchs,

    Dir fehlen Klammern. Du musst die komplette zweite Zeile nochmal einklammern.

    Grund: der ;? Operator hat in PHP die niedrigste Priorität. Alles, was vor dem ? steht, wird deshalb zuerst ausgewertet.

    Das ist ohne zusätzliche Klammern dies:

    $row_vip['email'] . ( $row_vip['email_2'] && strpos( $row_vip['email_2'], "@" ))

    In der Klammer steht ein boolescher Ausdruck, der zu TRUE auswertet (email_2 ist gefüllt und ein @ ist drin), das kettest Du an email an (wobei aus dem TRUE eine 1 wird) und erhältst jan@example.com1.

    Das ist truthy, deswegen wird der Teil zwischen ? und : erstellt und an $mailEmail zugewiesen.

    Das ist ein typischer Fall, wo man einen Ausdruck besser aufbricht statt eine lange Wurst zu konstruieren. ICH würde hier eine Funktion is_valid_email schreiben.

    $mailEmail = $row_vip['email'] 
               . (is_valid_email($row_vip['email_2']) ? ",".$row_vip['email_2'] : '');
    

    Oder vielleicht sogar besser noch

    $mailEmail = $row_vip['email'];
    if (is_valid_email($row_vip['email_2']))
    {
       $mailEmail .= "," . $row_vip['email_2'];
    }
    

    Das sind zwar vier Zeilen statt zwei, aber VIEL besser lesbar. Und der von PHP daraus erstellte Bytecode dürfte nicht ineffizienter sein als der inline-Ausdruck.

    Die is_valid_email Funktion kann deine eigenen Abfragen enthalten. Oder Du verwendest eine fertige PHP Funktion:

    function is_valid_email($mail) {
       return filter_var($mail, 
                         FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE) !== NULL;
    }
    

    Ist eigentlich garantiert, dass $row_vip['email'] immer gefüllt ist und ist nur email_2 optional?

    Rolf

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

      das geht übrigens noch einfacher, mit filter_var_array und array_filter (um die falschen Einträge rauszuschmeißen)

      $mailEmail = implode(
                     ",",
                     array_filter(
                       filter_var_array(
                         [ $row_vip['email'], $row_vip['email_2'] ],
                         FILTER_VALIDATE_EMAIL
                       )
                     )
                   );
      

      Man kann in Zeile 5 den Aufbau des Temp-Array vermeiden, indem man array_filter mit dem Modus ARRAY_FILTER_USE_BOTH benutzt, aber dann iteriert er durch das ganze $row_vip Array, man muss die benötigten Keys ausfiltern und filter_var einzeln pro Mailadresse aufrufen. Ich glaube nicht, dass das besser ist. Oder lesbarer.

      filter_var_array ersetzt die ungültigen Adressen durch false, und array_filter betrachtet sie damit als leer und entfernt sie. Der implode verkettet sie dann und trennt die Einträge durch Komma.

      Rolf

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

      Ist eigentlich garantiert, dass $row_vip['email'] immer gefüllt ist und ist nur email_2 optional?

      Im Prinzip ja, bei der Registrierung geht der Freischaltcode dahin.

      Rein technisch kann der Eigentümer des Kontos oder ein Admin die Mail löschen. Ist als Notbremse gegen automatische Mails zulässig.

      Gruß, Linuchs

      1. Hallo,

        Im Prinzip ja,

        Also nein…
        Dann willst du die erste mailadresse doch auch mit der neuen isValidMail-Funktion prüfen.

        Gruß
        Kalk

        1. Hallo Tabellenkalk,

          die Notation isValidMail entspricht auch meinem persönlichen Geschmack, aber ist nicht idiomatisch für PHP. Deswegen habe ich is_valid_email geschrieben. PHP benennt seine Funktionen in diesem Stil.

          Es sei denn, man möchte durch eine andere Namensnotation explizit zwischen PHP- und eigenen Funktionen unterscheiden.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo,

            von mir aus darf Linuchs seine Funktion auch „tut-die-übergebene-elektronische-Post-Adresse-meinen-Vorgaben-entsprechen-oder-nicht“ nennen…

            Gruß
            Kalk