Pit: Problem beim Nutzen einer klasse

Hallo,

ich wollte vorhin den phpmailer ab Vers.6 einbinden (ohne composer) und habe hierzu in mein Script folgende Zeilen eingefügt:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require __DIR__ . '/PHPMailer/src/Exception.php';
require __DIR__ . '/PHPMailer/src/PHPMailer.php';
require __DIR__ . '/PHPMailer/src/SMTP.php'; 

Daraufhin bleibt die Seite leer, aber auch im Errorlog läßt sich kein fatal error hierzu finden.

Kann man den Fehler im Script abfangen, damit ich weiß, was hier falsch läuft?

Pit

  1. Tach!

    Daraufhin bleibt die Seite leer, aber auch im Errorlog läßt sich kein fatal error hierzu finden.

    Kann man den Fehler im Script abfangen, damit ich weiß, was hier falsch läuft?

    Wenn das Script wegen sowas wie Syntaxfehler gar nicht kompiliert werden kann, kann es auch nicht loslaufen und irgendwelche Einstellungen darin berücksichtigen. Es kann sein, dass du mit display_startup_errors was angezeigt bekommst, das ist nämlich per Default ausgechaltet. Musst du aber in der globalen php.ini setzen, oder in .user.ini (bei Einbindung als FCGI) oder in der .htaccess (bei PHP als Apachemodul). Dort auch das error_reporting nicht vergessen, und display_errors kann auch nicht schaden. Das sollte aber nur in der Entwicklungsumgebung umgestellt werden, nicht auf produktiven Servern. Lieber weiße Seiten als Interna offenbaren.

    dedlfix.

    1. Hi dedlfix,

      ist ein bischen seltsam.

      Ich habe jetzt ein Testmailerscript umgeschrieben, bei dem ich

        //Klasse einbinden
        #require_once('../mailerclass/class.phpmailer.php');
      

      ausgetauscht habe gegen:

      use PHPMailer\PHPMailer\PHPMailer;
      use PHPMailer\PHPMailer\Exception;
      
      require __DIR__ . '/../PHPMailer/src/Exception.php';
      require __DIR__ . '/../PHPMailer/src/PHPMailer.php';
      require __DIR__ . '/../PHPMailer/src/SMTP.php'; 
      

      und es läuft tadellos.

      Bei einem anderen Script im selben Verzeichnis mache ich genau dasselbe und erhalte die weiße Seite.

      Beide Scripte laufen mit dem alten phpmailer und der require_once-Zeile auch tadellos.

      Aber nur eines der Beiden läßt sich problemlos auf den neuen phpmailer umstellen.

      Fazit bisher: Der obigen Pfade müssen korrekt sein, sonst würde Script1 umgestellt nicht laufen.

      Sonst noch was? Fehlerausgaben haben nciht funktioniert. Ich bin ein wenig verwundert, wie/wo ich weiter debuggen kann…

      Pit

      1. Hallo Pit,

        wenn das gute und das schlechte Script im gleichen Verzeichnis stehen, warum bindest Du den PHPMailer dann aus unterschiedlichen Verzeichnissen ein? Das wäre die Erklärung, weshalb es nicht funktioniert.

        Die Bedeutung von ../ ist Dir bekannt?

        Rolf

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

          wenn das gute und das schlechte Script im gleichen Verzeichnis stehen, warum bindest Du den PHPMailer dann aus unterschiedlichen Verzeichnissen ein? Das wäre die Erklärung, weshalb es nicht funktioniert.

          sorry für die Verwirrung. Ich habe im Vergleich zum ersten posting diese Tests in einem anderen Verzeichnis gemacht, daher mußte ich zum Einbinden eine Ebene höher gehen. Der Test war also ok.

          Die Bedeutung von ../ ist Dir bekannt?

          Jaja.

          Ich habe den Fehler (oder das Problem) bereits behoben...vielleicht kann mir das jemand erklären.

          Ich habe nun im 2. Script, das im Gegensatz zum ersten Testscript noch ein paar Zeilen Code vor dem Einbinden der Klasse enthielt, die obigen 5 Zeilen an den Scriptanfang verschoben. Und siehe da... nun funktioniert auch das 2. Script.

          Weiß jemand, warum das für Abhilfe sorgt?

          Pit

          --
          > sumpsi - posui - clusi
          1. Hallo Pit,

            ohne Kenntnis der paar Zeilen nicht.

            Entweder referenzieren die paar Zeilen den PHPMailer, oder sie verstellen was am System, das dazu führt, dass der PHPMailer sich unglücklich fühlt.

            Das globale Error-Reporting via PHP.INI hattest Du auf oberen Anschlag gedreht? Bzw. per .htaccess (hier haben sich ein paar Leute drüber unterhalten wie man das machen kann).

            Rolf

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

              Entweder referenzieren die paar Zeilen den PHPMailer, oder sie verstellen was am System, das dazu führt, dass der PHPMailer sich unglücklich fühlt.

              Das sind ganz normale php-Zeilen, die mit der Klasse noch gar nichts zu tun haben, sondern nur irgendwelche werte aus der db ziehen.

              Das globale Error-Reporting via PHP.INI hattest Du auf oberen Anschlag gedreht? Bzw. per .htaccess (hier haben sich ein paar Leute drüber unterhalten wie man das machen kann).

              Habe ich gemacht, es wurde mir aber kein einziger fatal error angezeigt. Aber ich habe den verdacht, dass der Log etwas hinterherhinkt. In Posting 1 hatte ich dasselbe ja auch erwähnt... inzwischen sind die fatal errors bzgl. des falschen Pfades aber eingetrudelt 😕

              --
              Was aber auch Probleme macht, ist die Einbindung innerhalb einer Funktion. Das klappte mit der alten phpmailer-Klasse über require_once('../pathto/class.phpmailer.php'); wunderbar. Aber dieses durch : ~~~php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; require DIR . '/../PHPMailer/src/Exception.php'; require DIR . '/../PHPMailer/src/PHPMailer.php'; require DIR . '/../PHPMailer/src/SMTP.php'; ~~~ ersetzen klappt gar nicht. Wenn jemand wüßte, warum, würde mir das schon helfen… Pit

              Was aber auch Probleme macht, ist die Einbindung innerhalb einer Funktion. Das klappte mit der alten phpmailer-Klasse über require_once('../pathto/class.phpmailer.php'); wunderbar. Aber dieses durch :

              use PHPMailer\PHPMailer\PHPMailer;
              use PHPMailer\PHPMailer\Exception;
              
              require __DIR__ . '/../PHPMailer/src/Exception.php';
              require __DIR__ . '/../PHPMailer/src/PHPMailer.php';
              require __DIR__ . '/../PHPMailer/src/SMTP.php';
              
              

              ersetzen klappt gar nicht.

              Wenn jemand wüßte, warum, würde mir das schon helfen…

              Pit

              1. Hallo Pit,

                die use Befehle legen fest, dass die Klassen PHPMailer und Exception aus dem Namespace PHPMailer\PHPMailer zu nehmen sind.

                Ein use-Befehl ist in einer Funktion nicht zulässig, er muss im "outermost scope" stehen, weil er vom Compiler ausgeführt wird und nicht zur Laufzeit. Sagt das PHP Handbuch.

                Also - ab auf die Schulbank und drück Dir rein, was es Seit PHP 5.3 mit namespaces und dem use Statement auf sich hat.

                Grundsätzlich sollte das so klappen wie Du es beschrieben hast, sogar mit require in einer Funktion. Ich habe das mal auf der Windows Kommandozeile ausprobiert (Spielplatz mit PHP 7.1):

                phpMailer.php:

                <?php
                namespace Foo;
                
                class PhpMailer 
                {
                   function send() 
                   {
                       echo "Bi Bi Bi Bipp!\n";
                   }
                }
                

                test.php:

                <?php
                use Foo\PhpMailer;
                
                function TEST() 
                {
                   require __DIR__ . "\PHPMailer.php";
                
                   $m = new PhpMailer();
                   $m->send();
                }
                
                TEST();
                

                Rolf

                --
                sumpsi - posui - clusi
                1. Halo Rolf,

                  Grundsätzlich sollte das so klappen wie Du es beschrieben hast, sogar mit require in einer Funktion. Ich habe das mal auf der Windows Kommandozeile ausprobiert (Spielplatz mit PHP 7.1):

                  Aah... sehr interessantes Beispiel.
                  Danke für diese Mühe! Mir hilft das total!

                  Ich werde das so mal in mein Beispiel übernehmen, leider komme da morgen erst zu. Aber Deine Begründung ist plausibel und wenn Du es sogar getestet hast...klasse. Mir helfen übrigens so ein paar Zeilen Code immer sehr viel weiter, weil ich nciht alle fachausdrücke kenne. Und die fachtermina zusammen mit einem Beispiel sind natürlich die creme de a creme für mich. So verstehe ich dann Beispiel und Fachtermina.

                  Danke!

                  Pit

                  1. Hallo Pit,

                    fachtermina

                    Wenn Du schon latinisiert.... Terminus ist O-Deklination, maskulinum. Der Plural ist Termini.

                    Termina wäre richtig, wenn der Singular Terminum (neutrum) hieße. Tut er aber nicht :)

                    Der berüchtigte Status ist eine Ausnahme, weil das ein Wort der U-Deklination ist. Dessen Plural lautet nicht Stati, wie man oft findet, sondern Status (Statuuuus gesprochen).

                    Warum? Frag die ollen Römer, die munter aus anderen Sprachen importiert und die Deklinationen übernommen haben.

                    Also - immer schön aufpassen mit den Termini technici 😂

                    Rolf

                    --
                    sumpsi - posui - clusi
                    1. Hallo Rolf B,

                      Der berüchtigte Status ist eine Ausnahme, weil das ein Wort der U-Deklination ist. Dessen Plural lautet nicht Stati, wie man oft findet, sondern Status (Statuuuus gesprochen).

                      Und Koituuuus.

                      Bis demnächst
                      Matthias

                      --
                      Pantoffeltierchen haben keine Hobbys.
  2. Hallo Forum,

    Meine Emails enthalten Unmengen von Umlautproblemen. Hier mal mein Quellcode.

    // Mailversand! 
    $absendeadresse = '';
    $cron = 'äöü';
    $myEmail = "";//Empfänger
    $myBetreff = "Testmail äüö";
    $myText = "Dies ist ein Test äöü";
    
    
    
      //Klasse einbinden
     # require_once('../../class.phpmailer.php');
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    
    require __DIR__ . '/../PHPMailer/src/Exception.php';
    require __DIR__ . '/../PHPMailer/src/PHPMailer.php';
    require __DIR__ . '/../PHPMailer/src/SMTP.php'; 
    
      
      //Instanz von PHPMailer bilden
      $mail = new PHPMailer();
      $mail->CharSet = "UTF-8";
     
      //Versand im HTML-Format festlegen
      $mail->IsHTML(true); 
    
      //Absenderadresse der Email setzen
      $mail->From = $absendeadresse;
      
      //Name des Abenders setzen
      $mail->FromName = "Pit";
      
      //Empfängeradresse setzen
      $mail->AddAddress($myEmail);
      
      //Betreff der Email setzen
      $mail->Subject = $myBetreff;
     
      //Body enthält die HTML-Nachricht
      $mail->Body    = nl2br($myText);
     
      //Altbody enthält alternative Textform
      $mail->AltBody = strip_tags($myText);
    
      //EMail senden und überprüfen ob versandt 
      if(!$mail->Send())
      {
         //$mail->Send() liefert FALSE zurück: Es ist ein Fehler aufgetreten
    	 echo("Fehler beim Versand");
    
      }
      else
      {
    //true
    	 echo("Versand!!");
      }
    

    Ergebnis: Dies ist ein Test ���

    1. Tach!

      Meine Emails enthalten Unmengen von Umlautproblemen.

      Die Frage is, welche Kodierung du verwendest. Die musst du dann auch im Header namens Content-Type angeben. Vielleicht hat der Mailer auch eine Funktion, um diese Angabe zu setzen.

      dedlfix.

      1. Tach!

        Die Frage is, welche Kodierung du verwendest. Die musst du dann auch im Header namens Content-Type angeben. Vielleicht hat der Mailer auch eine Funktion, um diese Angabe zu setzen.

        Hmm, fehlte da nicht eben noch die Zeile $mail->CharSet = "UTF-8";? Nun, damit hast du wohl angegeben, dass die Mail utf-8-kodiert sei. Ist das auch wahr für den Text. den du da übergibst? Der kodiert sich jedenfalls nicht so, weil du das möchtest, oder weil du das so deklarierst. Das ist nämlich nur ein Etikett. Dass der Inhalt dazu passt, musst du selbst sicherstellen.

        dedlfix.

        1. Tach!

          Die Frage is, welche Kodierung du verwendest. Die musst du dann auch im Header namens Content-Type angeben. Vielleicht hat der Mailer auch eine Funktion, um diese Angabe zu setzen.

          Hmm, fehlte da nicht eben noch die Zeile $mail->CharSet = "UTF-8";? Nun, damit hast du wohl angegeben, dass die Mail utf-8-kodiert sei. Ist das auch wahr für den Text. den du da übergibst? Der kodiert sich jedenfalls nicht so, weil du das möchtest, oder weil du das so deklarierst. Das ist nämlich nur ein Etikett. Dass der Inhalt dazu passt, musst du selbst sicherstellen.

          Hi dedlfix,

          Du hast recht!
          Mit
          $mail->CharSet = "ISO-8859-1"; gehts !

          Danke, Pit

          1. Tach!

            Mit
            $mail->CharSet = "ISO-8859-1"; gehts !

            Die zeitgemäßere Variante wäre, auf UTF-8 umzusteigen.

            dedlfix.

            1. Tach!

              Mit
              $mail->CharSet = "ISO-8859-1"; gehts !

              Die zeitgemäßere Variante wäre, auf UTF-8 umzusteigen.

              Hi dedlfix,

              das mache ich auch bei neuen Scripten, aber hier geht es um ein sehr großes System mit ewig vielen fpdf-Scripten. Und die kennen in der von mir verwendetetn Version nur ISO.

              Die Scripte umzuschreiben auf eine andere pdf-Klasse wäre unverhältnismäßig.

              Pit

    2. Hallo Pit,

      habe gerade mal wieder ein bisschen experimentiert:

      $x = "Hällo Wörld";
      echo strlen($x) . " - $x\n";
      
      $y = mb_convert_encoding($x, "UTF-8", "ISO-8859-1");
      echo strlen($y) . " - $y\n";
      

      Diese Sourcecode-Datei habe ich einmal in ISO-8859-1 und einmal in UTF-8 gespeichert.

      Ergebnis für ISO-8859-1 Sourcecode:

      11 - H#llo W#rld
      13 - Hällo Wörld
      

      D.h. PHP hat beim Ausgeben auf die Konsole eine UTF-8 Eingabe erwartet (weil das das default-charset meiner php.ini ist), die Ausgabe des nicht übersetzten Strings (11 Stellen) ging schief und die Ausgabe des übersetzten Strings (13 Stellen weil ä und ö 2 Bytes pro Zeichen brauchen) gelang.

      Ergebnis für UTF-8 Sourcecode:

      13 - Hällo Wörld
      17 - Hällo Wörld
      

      D.h. die unübersetzte Ausgabe war jetzt im erwarteten Format und der Versuch, das nochmal zu codieren, lieferte naturgemäß Unsinn.

      Für dein Mailing gilt: Wenn Du in UTF-8 mailen willst, deine Strings aber in ISO-8859-1 vorliegen, musst Du sie schön von Hand konvertieren.

      Fazit: Bei PHP muss man immer GANZ genau wissen, in welchem Encoding der Sourcecode vorliegt, und in welchem Encoding mit welchem Außensystem kommuniziert wird. Strings in PHP sind für die Standard-Stringfunktionen IMMER Bytesequenzen, diese Funktionen wissen nichts von Unicode. Das ist anders als in JavaScript. Deswegen musst Du, wenn Du deinen Sourcecode in UTF-8 speicherst, vermutlich alle Sourcen durchgehen, um zu prüfen, ob Du auf einmal UTF-8 und ISO-8859-1 Strings vermischst. Und eventuell auf die Funktionen der mbstring Extension umsteigen. Ganz einfach ist das bei Alt-Projekten nicht, denke ich mir.

      Rolf

      --
      sumpsi - posui - clusi
      1. Hi Rolf,

        wieder so ein geiles Beispiel. Dankeschön! Auch das werde ich am Wochenende versuchen, zu reproduzieren. Denn die Zeichensätze machen mir doch immer mal wieder ein paar Problemchen... 😉

        Pit

        1. Tach!

          Denn die Zeichensätze machen mir doch immer mal wieder ein paar Problemchen... 😉

          Grundsätzlich gibt es zwei Regeln zu beachten:

          • Ein System muss dem nachfolgenden System die verwendete Zeichenkodierung bekannt geben (und sich selbstverständlich auch daran halten).
          • Wenn ein System Daten nicht nur unverändert durchreicht, muss es mit der Zeichenkodierung korrekt umgehen können.

          Der Teufel steckt im Detail, weil die konkrete Umsetzung der beiden Punkte je System nicht selten unterschiedlich ist.

          dedlfix.

          1. Hallo dedlfix,

            und in machen Details stecken mehr Teufelchen als in anderen. PHP ist besonders hornig.

            Rolf

            --
            sumpsi - posui - clusi