tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
NEIN
ANTWORTEN
19
ZUGRIFFE
7405
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Abend!
    Ich habe vor langer Zeit mal eine kleine Klasse geschrieben mit der man Mails über Socket-Verbindungen verschicken kann. Dieses Script war eigentlich nur zur Übung gedacht und kam daher auch nie wirklich zum Einsatz. Auf die Idee kam ich durch die Tutorials Sending Email in PHP: The hacker way und Mailen mit PHP. Heute bin ich über dieses Script gestolpert und habe es als erstes auf den Stand von PHP5 gebracht. Da diese Klasse weder eine Möglichkeit zur Authentifizierung noch zum Versenden von Anhängen bietet, wollte ich dies noch hinzufügen. Gerade sitze ich an der Authentifizierung, der auch ein eigenes RFC (2554) gewidmet ist und verzweifel so ein bisschen. Zumindest wird die Mail versendet und kommt auch an. Leider gibt es jetzt einige Probleme.
    1. Betreff, Datum, Empfänger und Mailer werden in die Mail geschrieben
    2. Authentifizierung funktioniert nicht
    3. Fehler bei der Verarbeitung der CC- und BCC-Daten

    Wie der Aufruf der Klasse und der Verlauf des Protokolls aussieht, kann man hier sehen. (Werde dann wohl über jeden Klick auf diesen Link per Mail informiert ) In der Klasse sind zudem nützliche Methoden zu finden, die ich in anderen RFC basierten Klassen bereits verwendet habe und mit denen ich eigentlich sehr zufrieden bin. (log(), cmd(), getLog(), getReply()). Ich wäre sehr dankbar, wenn jemand mal über die Klasse schauen könnte und mir meine scheinbar geschlossenen Augen öffnen könnte.
    MfG, Andy
    Geändert von Avedo (05.06.08 um 10:07 Uhr)
     

  2. #2
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Morgen!
    Ich habe an der Klasse einiges geändert, doch leider bestehen die oben genannten Fehler immer noch. zudem bekomme ich sehr häufig den Fehler 500 Bad Syntax. Leider weiß ich nicht woran das liegt, denn eigentlich ist alles korrekt gesendet. Wäre euch echt dankbar für einige Tipps und Anregungen. Das Testscript ist weiterhin online.
    MfG, Andy

    PS: Der Inhalt der Ankommenden Mail sieht so aus:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    Subject: Sending mail via PHP!
     
    Date: Thu, 05 Jun 2008 10:03:34 +0200
     
    To: , Andreas2209@web.de
     
    X-Mailer: SMTP Class
     
     
     
    Hello. If you can read this message, I was able to send my first mail with my new SmtpConnect-Class. MfG, Andy
    Ein Betreff existiert nicht und als empfänger steht undisclosed-recipients:;

    SmtpConnect.php
    PHP-Code:
    <pre>

    <?php  
    error_reporting
    (E_ALL);

    /***
    * The SmtpConnect class allows sending mails via SMTP
    *  
    * @package SmtpConnect
    * @version 0.2
    * @author Andreas Wilhelm <Andreas2209@web.de>
    * @copyright Andreas Wilhelm
    **/  
    class SmtpConnect 
    {
        
    // declare class variables
        
    private $host
        private 
    $port;
        private 
    $user;
        private 
    $pwd;
        
        private 
    $cc;
        private 
    $bcc;
        
        private 
    $sock;    
        
        private 
    $log;

        
    /**
        * Constructor - Is called when the class is instanced
        *
        * @access: public
        * @param Str $host
        * @param Int $port
        * @param Bool $log    
        * @return NONE
        */
        
    public function __construct($host='localhost'$port=25)
        {
            
    // set server-variables
            
    $this->host $host;
            
    $this->port $port;
        }

        
    /**
        * connect() - Connects to the given smtp-server
        *
        * @access: public
        * @return Handle
        */
        
    public function connect()
        {        
            
    // control-connection handle is saved to $handle
            
    $this->sock = @fsockopen($this->host$this->port);
            if (!
    $this->sock)
                throw new 
    Exception("Connection failed."); 
            
            
    // switch to non-blocking mode - just return data no response
            
    set_socket_blocking($this->socktrue);
            
            
    // set timeout of the server connection
            
    stream_set_timeout($this->sock0200000);
            
            return 
    true;
        }

        
    /**
        * auth() - Saves the data for authorisation
        *
        * @access: public
        * @param Str $user
        * @param Str $pwd
        * @return NONE
        */
        
    public function auth($user$pwd)
        {
            
    // save user and password for authorisation
            
    $this->user $user;
            
    $this->pwd $pwd;
        }
        
        
    /**
        * setCc() - Sets the carbon copy header
        *
        * @access: public
        * @param Str $cc
        * @return NONE
        */
        
    public function setCc($cc)
        {
            if ( !empty(
    $cc) )
            {
          
    // split string into an array
          
    $cc split(","$cc);
          
          
    // check if all mail-addresses valid
          
    foreach($cc as &$mail)
          {
                    
    $mail trim($mail);
            if( !
    filter_var($mailFILTER_VALIDATE_EMAIL) )
            {
              throw new 
    Exception("Invalid mail-address $mail.");
            }
            
            else
            {          
              
    // modify mail-address
              
    $mail "<$mail>";
            }
          }
            
          
    // create list of mails
          
    $newCc implode(","$cc);
          
          
    $this->cc $newCc;
            }
        }
        
        
    /**
        * setBcc() - Sets the blind carbon copy header
        *
        * @access: public
        * @param Str $bcc
        * @return NONE
        */
        
    public function setBcc($bcc)
        {
            if ( !empty(
    $bcc) )
            {
          
    // split string into an array
          
    $bcc split(","$bcc);
          
          
    // check if all mail-addresses valid
          
    foreach($bcc as $key => $mail)
          {
                    
    $mail trim($mail);
            if( !
    filter_var($mailFILTER_VALIDATE_EMAIL) )
            {
              throw new 
    Exception("Invalid mail-address $mail.");
            }
            
            else
            {          
              
    // modify mail-address
              
    $mail "<$mail>";
            }
          }
            
          
    // create list of mails
          
    $newBcc implode(","$bcc);
          
          
    $this->bcc $newBcc;
            }
        }

        
    /**
        * send() - Checks the  given data and send  a mail via smtp
        *
        * @access: public
        * @param Str $from
        * @param Str $to
        * @param Str $subject
        * @param Str $message
        * @return Boolean
        */
        
    public function send($from$to$subject$message)
        {                
            
    // check if an addressor is specified
            
    if( empty($from) )
            {
                throw new 
    Exception('No addressor specified.');
            }
            
            
    // check if mail-address is valid
            
    if ( !filter_var($fromFILTER_VALIDATE_EMAIL) )
            {
                throw new 
    Exception("Invalid mail-address $from.");
            }
            
            
    // check if email adress is specified
            
    if( empty($to) )
            {
                throw new 
    Exception('No email address specified.');
            }
            
            else
            {
          
    // save mail addresses to an array
          
    $to explode(","$to);
          
          
    //check if mail-addresses are valid
          
    foreach($to as &$mail)
          {
            if( !
    filter_var($mailFILTER_VALIDATE_EMAIL) )
            {
              throw new 
    Exception("Invalid mail-address $mail.");
            }
            
            
    // build to-header
            
    else
            {
              
    // modify mail-address
              
    $mail "<$mail>";     
            }
          }
                
          
    // create list of mails
          
    $toHeader implode(","$to);
            }        
            
            
    // check if a subject is set
            
    if( empty($subject) )
            {
                throw new 
    Exception('Subject is empty.');
            }
            
            
    // make message RFC821 compliant
            
    $message preg_replace("/(?<!\r)\n/si""\r\n"$message);
            
            
    // check if a message is given
            
    if( empty($message) )
            {
                throw new 
    Exception('Message is empty.');
            }

            
    // connect to the server
            
    $this->connect();
        
            if(
    $this->sock)
            {
                
    $this->check('220');
        
                if( !empty(
    $this->user) && !empty($this->pwd) )
                {
                    
    // send EHLO -spezified in RFC 2554
                    
    $this->cmd("EHLO " $this->host);
                    
    $this->check('250');
            
                    
    $this->cmd("AUTH LOGIN");
                    
    $this->check('334');
                    
    $this->cmd(base64_encode($this->user));
                    
    $this->check('334');
                    
    $this->cmd(base64_encode($this->pwd));
                    
    $this->check('235');
                }
                
                else
                {
                    
    // Send the RFC821 specified HELO.
                    
    $this->cmd('HELO ' $this->host);
                    
    $this->check('250');
                }
        
                
    // specify addressor
                
    $this->cmd("MAIL FROM: <$from>");
                
    $this->check('250');
        
                
    // send to-header
          
    $this->cmd("RCPT TO: $toHeader");
                
    $this->check('250');
            
                
    // initiate data-transfere
                
    $this->cmd('DATA'); 
        
                
    // check the reply
                
    $this->check('354');
        
                
    // send date
                
    $this->cmd("Date: ".date('r'));
                
    $this->check('250');
        
                
    // specify addressor
                
    $this->cmd("From: <$from>");
        
                
    // send subject
                
    $this->cmd("Subject: $subject");
        
                
    // send reply-to-header
          
    $this->cmd("Reply-To: $toHeader");
        
                
    // send to-header
          
    $this->cmd("To: $toHeader");
                
                
    // send cc
          
    $this->cmd('CC: ' $this->cc);
                
                
    // send bcc
          
    $this->cmd('BCC: ' $this->bcc);
        
                
    // smtp mailer-header
                
    $this->cmd("X-Mailer: SMTP Class\r\n");
        
                
    // send the message
                
    $this->cmd("$message\r\n");
        
                
    // send end parameter
                
    $this->cmd('.');
                
                if( !
    $this->check('250') )
                {
                    
    $this->cmd('QUIT');
                    
    fclose($this->sock);
                    return 
    false;
                }
        
                
    // quit and close socket
                
    $this->cmd("QUIT"); 
                
    $this->check('221');
                
    fclose($this->sock);    
                return 
    true;
            }
            
            else
            {
                return 
    false;
            }
        }

        
    /**
        * cmd() - Sets a ftp-command given by the user
        *
        * @access: public
        * @param Str $cmd
        * @return NONE
        */
        
    public function cmd($cmd)
        {
            
    fputs($this->sock"$cmd\r\n");
            
    $this->log("&gt; $cmd");
        }    
        
        
    /**
        * getReply() - Gets the reply of the ftp-server
        *
        * @access: public
        * @param Int $i
        * @return String
        */
        
    public function getReply($i 0)
        {
            
    $go true;
            
    $message "";
            
            do 
            {    
                
    $tmp = @fgets($this->sock1024);
                if(
    $tmp === false
                {
                    
    $go false;
                } 
                
                else 
                {
                    
    $message .= $tmp;
                    if( 
    preg_match('/^([0-9]{3})(-(.*[\r\n]{1,2})+\\1)? [^\r\n]+[\r\n]{1,2}$/'$message) ) $go false;
                }
            } while(
    $go);
            
            
    $this->log($message);
            
            return 
    $message;
        }

        
    /**
        * checkControl() - Checks if the response of a command is ok
        *
        * @access: public
        * @param Str $reply
        * @return Boolean
        */
        
    public function valid()
        {
            
    // get response of the server
            
    $this->response $this->getReply();
            
            
    // check the response and say if everything is allright
            
    return (empty($this->response) || preg_match('/^[5]/'$this->response)) ? false true;
        }
            
        
    /**
        * check() - Checks if the response-code is correct
        *
        * @access: public
        * @param Str $code
        * @return Boolean
        */
        
    public function check($code)
        {
            if(
    $this->valid())
            {
                
    $pat '/^'$code .'/';
                if( 
    preg_match($pat$this->response))
                {
                    return 
    true;
                }                
            }    
                
            return 
    false;
        }
                
        
    /**
        * log() - Saves all request to the server and their responses into $this->log
        *
        * @access: private
        * @return NONE
        */
        
    private function log($str)
        {
            
    $this->log .= "$str<br>";
        }
                
        
    /**
        * getLog() - Prints out all requests to the server and their responses 
        *
        * @access: public
        * @return NONE
        */
        
    public function getLog()
        {
            return 
    $this->log;
        }

    }

    try
    {
        
    $from 'pseudo@web.de';
        
    $to 'Andreas2209@web.de';
        
    $subject 'Sending mail via PHP!';
        
    $message 'Hello. If you can read this message, I was able to send my first mail with my new SmtpConnect-Class. MfG, Andy';

        
    $mail = new SmtpConnect('localhost'25);
        
    $mail->setCc('psycho@web.de, bombe@gmx.net');
        
    $mail->setBcc('lol@hotmail.com, gummi@web.de');
        
    $mail->send($from$to$subject$message);
        echo 
    $mail->getLog();
    }

    catch(
    Exception $e
    {
        echo 
    $e->getMessage();
    }
    ?>

    </pre>
    Geändert von Avedo (05.06.08 um 17:18 Uhr)
     

  3. #3
    Avatar von Dennis Wronka
    Dennis Wronka Dennis Wronka ist offline Soulcollector
    Registriert seit
    Apr 2002
    Ort
    Hong Kong
    Beiträge
    12.296
    Blog-Einträge
    231
    Ich hab nicht nur eine Klasse fuer HTTP, sondern auch eine fuer SMTP.
    Wenn Du's nicht eilig hast solltest Du noch ein paar Stunden warten, denn heut Abend will ich schauen dass ich die aktuelle Release-Fassung hochlade.

    Hier gibt es auch ein Tutorial zu der Klasse, aber das basiert auf der ersten Version und ist noch "etwas" fehlerhaft.
    Was mich daran erinnert dass ich noch ein paar Tutorials zu aktualisieren habe...
     
    PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
    Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
    __________________
    EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
    EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
    __________________
    Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
    __________________
    Zitat Zitat von Friedrich Nietzsche
    Man muss noch Chaos in sich haben, um einen tanzenden Stern gebaeren zu koennen.

  4. #4
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Wow du hast schon einige Klassen verfasst! Gibts dazu auch ne Übersicht? Beschäftige mich gerade im Rahmen eines Projektes mit den wichtigsten RFCs und zudem möchte ich so auch meine PHP-Kenntnisse verbessern. Dabei soll auch ein besonderes Augenmerk auf OOP liegen.
    MfG, Andy
     

  5. #5
    Avatar von Loomis
    Loomis Loomis ist offline Mitglied Bunt
    Registriert seit
    Jul 2002
    Ort
    Aschaffenburg
    Beiträge
    1.538
    Der Link zu Dennis` Klassen steht ja in der Signatur ("PHP Class Collection")
     

  6. #6
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Ich finde, du solltest die SMTP-Klasse nicht überladen. So sollte die SMTP-Klasse nur für die Kommunikation zwischen Client und SMTP-Server zuständig sein. Der Rest, beispielsweise das Verfassen einer E-Mail-Nachricht, sollte eine andere Instanz übernehmen.
     
    Markus Wulftange

  7. #7
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    @Loomes Manchmal sollte man sich vielleicht doch die Signaturen der anderen ansehen. Sind schon einige Klasse. Nette Dinge dabei.

    @Gumbo Verstehe deinen Einwand nicht so ganz. Was meinst du damit?

    @all
    Die Header werden nun richtig gesendet. Die Funktionstüchtigkeit bei Authentifizierung habe ich noch nicht getestet. Der Fehler bei der Verarbeitung besteht noch, habe mich allerdings auch noch nicht darum gekümmert. Es gibt aber noch ein Problem bei der Verarbeitung der Empfänger-Daten. Der betreffende Code-Ausschnitt sieht momentan so aus. Leider gibt es trotz error_reporting(E_ALL) keine Fehlermeldungen.

    PHP-Code:
            // check if email adress is specified
            
    if( empty($to) )
            {
                throw new 
    Exception('No email address specified.');
            }
            
            else
            {
          
    // save mail addresses to an array
          
    $to explode(","$to);
          
          
    //check if mail-addresses are valid
          
    foreach($to as &$mail)
          {
            if( !
    filter_var($mailFILTER_VALIDATE_EMAIL) )
            {
              throw new 
    Exception("Invalid mail-address $mail.");
            }
            
            
    // build to-header
            
    else
            {
              
    // modify mail-address
              
    $mail "<$mail>";     
            }
          }
                
          
    // create list of mails
          
    $toHeader implode(","$to);
            } 
    MfG, Andy
     

  8. #8
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Den Aufgaben deiner Klasse nach zu urteilen, müsste sie eher „EmailComposerAndSubmitterViaSmtp“ heißen, da sie ja nicht nur eine Verbindung zum SMTP-Server aufbaut sondern auch noch eine E-Mail verfasst und diese verschickt.
     
    Markus Wulftange

  9. #9
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Da magst du recht habe, aber ich denke nicht, dass es sehr sinnvoll ist eine reine Verbindung zu einem SMTP-Server herzustellen. Die Klasse macht ja nichts anderes, als gegebene Inhalte über die Verbindung zu versenden. Damit das Sinn macht muss ich diese Inhalte halt auch auf ihre Korrektheit überprüfen. Kann sie ja gerne umtaufen in SmtpMail().
    MfG, Andy

    PS: Habe oben mal die geänderte Klasse hochgeladen. Hat leider noch ein paar Fehler.
     

  10. #10
    Avatar von Dennis Wronka
    Dennis Wronka Dennis Wronka ist offline Soulcollector
    Registriert seit
    Apr 2002
    Ort
    Hong Kong
    Beiträge
    12.296
    Blog-Einträge
    231
    Wie Du eventuell gesehen hast hab ich dies bei mir gesplittet.
    Grund ist eben der von Gumbo genannte, dass man eben getrennte Klassen fuer spezialisierte Aufgaben hat.
    Und man kann die mit meiner Mail-Klasse erstellten Mails ja auch ueber mail() versenden, was ja nun auch in der aktuellen Version mit in der Klasse integriert ist.

    Was fuer Probleme hast Du denn noch bei Deiner Klasse? Gibt es Fehlermeldungen?
    Wie hast Du das SMTP-Protokoll implementiert? Hast Du Dich lediglich am RFC orientiert oder hast Du auch echten SMTP-Traffic analysiert.
    Fuer mich hab ich festgestellt dass ich wesentlich schneller zum Ergebnis (also dem implementierten Protokoll) komme wenn ich mir mit Wireshark echten Traffic anschaue.
     
    PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
    Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
    __________________
    EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
    EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
    __________________
    Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
    __________________
    Zitat Zitat von Friedrich Nietzsche
    Man muss noch Chaos in sich haben, um einen tanzenden Stern gebaeren zu koennen.

  11. #11
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Hallo!
    Also ich habe mich vorallem mit dem RFC beschäftigt und mir das Log von meiner Verbindung angeschaut, dass in der Klasse mitgeschrieben wird. Zu den Fehlermeldungen: Es gibt leider keine. Es ist etwas verwirrend. Wie du dem Codeschnipsel entnehmen kannst, den ich als letztes gepostet habe, verarbeite ich die Empfänger-Daten so, dass es keinen Fehler beim Versenden gibt. Das geänderte wird dann in $toHeader gespeichert. Leider ist diese Variable leer. Komischerweise wird die Mail trotzdem versendet und kommt auch an. Weißt du wieso das so ist? Wo liegt der Fehler? Werde die Klasse nachher nochmal so umbasteln, dass eben die Verarbeitung der übergebenen Daten wegfällt und eben nur die Daten gesendet werden. Das mitloggen werde ich allerdings lassen, da ich das ganz praktisch finde. Dann werde ich auch eine Klasse Mail extends SmtpConnect schreiben, die ähnlich der mail()-Funktion aufgebaut sein wird. So war doch eure Anmerkung gemeint oder nicht?
    MfG, Andy
     

  12. #12
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Naja, eine Mail-Klasse ist eigentlich keine Spezialisierung einer SMTP-Klasse, wozu Vererbungen eigentlich verwendet werden. Es ist wenn überhaupt eine Helferklasse, da sie sich nur die Funktionen der SMTP-Klasse zunutze macht. Aber selbst das schränkt den Einsatzradius der Mail-Klasse stark ein.
     
    Markus Wulftange

  13. #13
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    ch werde es glaube ich einfach bei einer Klasse belassen. Überarbeiten muss ich die Klasse trotzdem kmplett. Würde mich allerdings sehr freuen, wenn mir jemand bei dem oberen Code-Schnipsel noch helfen könnte. Warum ist nach folgender Zeile das Array $to leer?
    PHP-Code:
    $mail "<$mail>"
    MfG, Andy
     

  14. #14
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Guten Morgen!
    Ich hatte gerade mal wieder Zeit und Lust mich an die SmtpMail-Klasse zu setzen. Ich habe mal deinen Rat Gumbo befolgt und nur die grundlegenden Befehle des Simple Mail Transfer Protocols in einzelnen Methoden zusammengefasst, auf denen man nun weiter aufbauen kann. Nun könnte man zum Beispiel noch eine Klasse Mail schreiben, die mit Hilfe dieser Methoden das verschicken von Mails und vielleicht sogar das hinzufügen von Anhängen vereinfacht. Was haltet ihr denn nun von dieser SMTP-Klasse? Ist sie so wie sie nun ist besser als vorher und ist es auch das , was du meintest Gumbo? Würde mich über Rückmeldungen und Anregungen freuen.
    MfG, Andy

    PS: Ein brauchbarer Beispiel-Aufruf der Klasse ist auch am Ende des Spripts enthalten.


    SmtpMail.php
    PHP-Code:
    <?php  
    error_reporting
    (E_ALL);

    /***
    * The SmtpMail class allows sending mails via SMTP
    *  
    * @package SmtpMail
    * @version 0.3
    * @author Andreas Wilhelm <Andreas2209@web.de>
    * @copyright Andreas Wilhelm
    **/  
    class SmtpMail 
    {
        
    // declare class variables
        
    private $host
        private 
    $port;
        
        private 
    $sock;    
        
        private 
    $log;

        
    /**
        * Constructor - Is called when the class is instanced
        *
        * @access: public
        * @param Str $host
        * @param Int $port
        * @return NONE
        */
        
    public function __construct($host='localhost'$port=25)
        {
            
    // set server-variables
            
    $this->host $host;
            
    $this->port $port;
        }

        
    /**
        * connect() - Connects to the given smtp-server
        *
        * @access: public
        * @return Boolean
        */
        
    public function connect()
        {        
            
    // control-connection handle is saved to $handle
            
    $this->sock = @fsockopen($this->host$this->port);
            if ( !
    $this->sock OR !$this->check('220') )
                throw new 
    Exception("Connection failed."); 
            
            
    // switch to non-blocking mode - just return data no response
            
    set_socket_blocking($this->socktrue);
            
            
    // set timeout of the server connection
            
    stream_set_timeout($this->sock0200000);
            
            return 
    true;
        }

        
    /**
        * ehlo() - Sends greeting to secured server
        *
        * @access: public
        * @param Str $user
        * @param Str $pwd
        * @return Boolean
        */
        
    public function ehlo($user$pwd)
        {
            
    // send EHLO -spezified in RFC 2554
            
    $this->cmd("EHLO " $this->host);
            if( !
    $this->check('250') )
                throw new 
    Exception("Failed to send EHLO.");
            
            
    // send authentification-identifier
            
    $this->cmd("AUTH LOGIN");        
            if( !
    $this->check('334') )
                throw new 
    Exception("Failed to send AUTH.");
            
            
    // send user-name
            
    $this->cmd(base64_encode($this->user));        
            if( !
    $this->check('334') )
                throw new 
    Exception("Failed to send user-name.");
            
            
    // send password
            
    $this->cmd(base64_encode($this->pwd));
            if( !
    $this->check('235') )
                throw new 
    Exception("Failed to send password.");
            
            return 
    true;
        }

        
    /**
        * helo() - Sends greeting to server
        *
        * @access: public
        * @return Boolean
        */
        
    public function helo()
        {
            
    // Send the RFC821 specified HELO.
            
    $this->cmd('HELO ' $this->host);    
            if( !
    $this->check('250') )
                throw new 
    Exception("Failed to send HELO.");
            
            return 
    true;
        }

        
    /**
        * from() - Sends specified addressor
        *
        * @access: public
        * @param Str $from
        * @return Boolean
        */
        
    public function from($from)
        {
            
    // specify addressor
            
    $this->cmd("MAIL FROM: $from");
            if( !
    $this->check('250') )
                throw new 
    Exception("Failed to send addressor.");
            
            return 
    true;
        }

        
    /**
        * rcpt() - Sends specified acceptor
        *
        * @access: public
        * @param Str $to
        * @return Boolean
        */
        
    public function rcpt($to)
        {
            
    // send specified acceptor
            
    $this->cmd("RCPT TO: $to");        
            if( !
    $this->check('250') )
                throw new 
    Exception("Failed to send acceptor.");
            
            return 
    true;
        }
      
        
    /**
        * data() - Sends the data to the server
        *
        * @access: public
        * @param Str $message
        * @param Arr $header
        * @return NONE
        */      
        
    public function data($message$header)
        {
            
    // initiate data-transfere
            
    $this->cmd('DATA'); 
            if( !
    $this->check('354') )
                throw new 
    Exception("Data-transfere failed.");
                
            
    // validate header-data
            
    if( !is_array($header) )
                throw new 
    Exception("Header-data must be an array.");
                
            
    // initiate counter
            
    $i 0;
                
            
    // include header data
            
    foreach( $header as $key => $value)
            {
                
    // send header
                
    if( $i count($header)-)
                {
                    
    $this->cmd("$key$value");
                }
                
                else
                {
                    
    $this->cmd("$key$value\r\n");            
                }
                
                
    $i++;            
            }
        
            
    // send the message
            
    $this->cmd("$message\r\n");
        
            
    // send end parameter
            
    $this->cmd('.');
            
            
    $this->check('250');
        }
      
        
    /**
        * quit() - Closes the server-connection
        *
        * @access: public
        * @return NONE
        */      
        
    public function quit()
        {
            
    $this->cmd("QUIT"); 
            
    $this->check('221');
            
    fclose($this->sock);    
            return 
    true;
        }

        
    /**
        * cmd() - Sets a ftp-command given by the user
        *
        * @access: public
        * @param Str $cmd
        * @return NONE
        */
        
    public function cmd($cmd)
        {
            
    fputs($this->sock"$cmd\r\n");
            
    $this->log("&gt; $cmd");
        }    
        
        
    /**
        * getReply() - Gets the reply of the ftp-server
        *
        * @access: public
        * @return String
        */
        
    public function getReply()
        {
            
    $go true;
            
    $message "";
            
            do 
            {    
                
    $tmp = @fgets($this->sock1024);
                if(
    $tmp === false
                {
                    
    $go false;
                } 
                
                else 
                {
                    
    $message .= $tmp;
                    if( 
    preg_match('/^([0-9]{3})(-(.*[\r\n]{1,2})+\\1)? [^\r\n]+[\r\n]{1,2}$/'$message) ) $go false;
                }
            } while(
    $go);
            
            
    $this->log($message);
            
            return 
    $message;
        }

        
    /**
        * checkControl() - Checks if the response of a command is ok
        *
        * @access: public
        * @param Str $reply
        * @return Boolean
        */
        
    public function valid()
        {
            
    // get response of the server
            
    $this->response $this->getReply();
            
            
    // check the response and say if everything is allright
            
    return (empty($this->response) || preg_match('/^[5]/'$this->response)) ? false true;
        }
            
        
    /**
        * check() - Checks if the response-code is correct
        *
        * @access: public
        * @param Str $code
        * @return Boolean
        */
        
    public function check($code)
        {
            if(
    $this->valid())
            {
                
    $pat '/^'$code .'/';
                if( 
    preg_match($pat$this->response))
                {
                    return 
    true;
                }                
            }    
                
            return 
    false;
        }
                
        
    /**
        * log() - Saves all request to the server and their responses into $this->log
        *
        * @access: private
        * @return NONE
        */
        
    private function log($str)
        {
            
    $this->log .= "$str<br>";
        }
                
        
    /**
        * getLog() - Prints out all requests to the server and their responses 
        *
        * @access: public
        * @return NONE
        */
        
    public function getLog()
        {
            return 
    $this->log;
        }

    }

    try
    {            
        
    $from 'pseudo@web.de';
        
    $to 'fantasy@web.de';
        
    $date date('r');
        
    $header = array( 
            
    'Date' => $date,
            
    'From' => $from,
            
    'Subject' => 'Sending mail via PHP!',
            
    'To' => $to,
            
    'X-Mailer' => 'Avedo - SmtpMail');
        
    $message "Hello. \nIf you can read this message, I was able to send my first mail with my new SmtpMail-Class. \nThat's great! So have a beer and enjoy the show! \nMfG, Andy";

        
    $mail = new SmtpMail('localhost'25);
        
    $mail->connect();
        
    $mail->helo();
        
    $mail->from($from);
        
    $mail->rcpt($to);
        
    $mail->data($message$header);
        
    $mail->quit();
        echo 
    $mail->getLog();
    }

    catch(
    Exception $e
    {
        echo 
    $e->getMessage();
    }
    ?>
     

  15. #15
    Avatar von Dennis Wronka
    Dennis Wronka Dennis Wronka ist offline Soulcollector
    Registriert seit
    Apr 2002
    Ort
    Hong Kong
    Beiträge
    12.296
    Blog-Einträge
    231
    Hab mal fix drueber geschaut und die Klasse sieht soweit schonmal nicht schlecht aus.
    Ein paar Anmerkungen hab ich aber:
    • Mir ist bei den Tests zu meiner Klasse kein einziger Mail-Server ueber den Weg gelaufen der HELO verlangt und EHLO nicht unterstuetzt. Es mag da vielleicht noch ein paar Ausnahmen geben, aber jeder aktuelle Mail-Server sollte EHLO unterstuetzen.
    • Der Weg ueber EHLO setzt nicht voraus dass der User sich authentifiziert. Entsprechend ist der Login-Code dort meiner Meinung nach falsch platziert.
    • LOGIN ist die unsicherste Authentifizierungsmethode die fuer SMTP verfuegbar ist. Aehnlich einfach zu implementieren, aber zumindest ein klein wenig sicherer (wenngleich nicht viel) ist PLAIN.
      Zusaetzlich zu diesen beiden einfach Methoden empfehle ich noch die Nutzung einer der sichereren Methoden wie z.B. CRAM-MD5 oder Digest-MD5, denn nicht alle Dienste unterstuetzen PLAIN oder gar LOGIN. Wenn ich mich recht erinnere laesst GMail Dich damit z.B. nicht rein.
      Wenn Du die 4 genannten Mechanismen unterstuetzt solltest Du aber im Grunde mit jedem SMTP-Server der Logins unterstuetzt arbeiten koennen. Wenn Du's ganz wild willst kannst Du ja auch noch NTLM hinzufuegen.
      Informationen findest Du hier.
    • SSL-Support waere auch keine so schlechte Idee und ist einfach zu implementieren.
     
    PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
    Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
    __________________
    EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
    EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
    __________________
    Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
    __________________
    Zitat Zitat von Friedrich Nietzsche
    Man muss noch Chaos in sich haben, um einen tanzenden Stern gebaeren zu koennen.

Ähnliche Themen

  1. E-Mail versenden mit Anhang per SMTP
    Von Xing_bimbo im Forum PHP
    Antworten: 1
    Letzter Beitrag: 10.06.10, 13:52
  2. e-Mail versenden über POP/SMTP
    Von liquidbeats im Forum PHP
    Antworten: 12
    Letzter Beitrag: 20.08.05, 15:27
  3. VB6.0 mail versenden smtp
    Von itsme123 im Forum Visual Basic 6.0
    Antworten: 1
    Letzter Beitrag: 04.03.05, 17:22
  4. Camspy SMTP --- Kein E-Mail Upload auf SMTP Server
    Von wighlander im Forum Internet, DSL & Flatrate
    Antworten: 1
    Letzter Beitrag: 24.02.05, 03:47
  5. Camspy SMTP --- Kein E-Mail Upload auf SMTP Server
    Von wighlander im Forum Microsoft Windows
    Antworten: 1
    Letzter Beitrag: 23.02.05, 13:35