POP3 Postfach über PHP auslesen und in Datenbank speichern

Bash, Shell, PHP, Python, Perl, CGI
getmuzic.de
Posts: 6
Joined: 2006-10-15 01:03

POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by getmuzic.de »

Hallo Boardies,

mein Vorhaben möchte ich kurz erläutern.

Ich möchte in meiner kleinen Community jedem User eine eMail-Adresse anbieten. Allerdings ohne "HORDE" und die ganzen WebMail-Systeme, sondern ein Selbstgeschriebenes, dass auch in die Site der Community passt.

Dazu hab ich mir einige Gedanken gemacht und möchte sie hier kund tun, damit Ihr das etwas besser versteht.

Ich habe ein POP3-Konto angelegt und so konfiguriert, dass alle Mails, egal an wen adressiert dort hinein gelangen. Dann ging ich auf die Suche nach einer Möglichkeit, das Pop3-Konto über PHP wieder auszulesen und die Daten in eine Datenbank zu schreiben. Ich fand dann folgendes Script:

Code: Select all

// Wartet auf "+OK", oder "-ERR"
function pop3_wait4result( $handle )
{
    while( $wait_result = fgets( $handle, 256 ) )
    {
        if( substr( $wait_result, 0, 1 ) == "-" )
            return $wait_result;
        if( substr( $wait_result, 0, 1 ) == "+" )
            return $wait_result;
    }
}

// Lade Status der POP3 Mailbox
function pop3_getstat( $addr, $port, $user, $pass, $timeout, $quit_handle )
{
    // RETURN ARRAY POP3_GETSTAT
    $stat_array =     array(     "handle" => @fsockopen( $addr, $port, $errno, $errstr, $timeout ),
                "init" => FALSE,
                "user" => FALSE,
                "pass" => FALSE,
                "status" => FALSE );

    // BENUTZE HANDLE BIS STAT
    if( $stat_array[ "handle" ] )
        {
        socket_set_timeout( $stat_array[ "handle" ], $timeout );
        // Connect Antwort laden
        $stat_array[ "init" ] = pop3_wait4result( $stat_array[ "handle" ] );
        // Benutzer senden
        fputs( $stat_array[ "handle" ], "USER $userrn" );
        $stat_array[ "user" ] = pop3_wait4result( $stat_array[ "handle" ] );
        // Passwort senden
        fputs( $stat_array[ "handle" ], "PASS $passrn" );
        $stat_array[ "pass" ] = pop3_wait4result( $stat_array[ "handle" ] );
        // Status abfragen
        fputs( $stat_array[ "handle" ], "STATrn" );
        $stat_array[ "status" ] = pop3_wait4result( $stat_array[ "handle" ] );
        // Handle schließen
        if( $quit_handle )
        {
            fputs( $stat_array[ "handle" ], "QUITrn" );
            $stat_array[ "handle" ] = fgets( $stat_array[ "handle" ] );
        }
    } else $stat_array[ "handle" ] = FALSE;

    return $stat_array;
}

// Liste der Mails abrufen
function pop3_getmessagelist( $handle, $quit_handle )
{
    // RETURN ARRAY GET_MESSAGELIST
    $messagelist_arr =     array( 0 => array( "message_nr" => FALSE, "message_size" => FALSE ) );

    fputs( $handle, "LISTrn" );
    $list_return = pop3_wait4result( $handle );
    if( strstr( $list_return, "+OK" ) )
    {
        $i = 0;
        while( $list_return = fgets( $handle ) )
        {
            if( !strstr( $list_return, "." ) )
            {
                $list_return_arr = explode( " ", $list_return );
                $messagelist_arr[ $i ][ "message_nr" ] = $list_return_arr[ 0 ];
                $messagelist_arr[ $i ][ "message_size" ] = $list_return_arr[ 1 ];
                $i++;
            }
            else break;
        }
    }

    // Handle schließen
    if( $quit_handle )
    {
        fputs( $handle, "QUITrn" );
        $handle = fgets( $handle );
    }

    return $messagelist_arr;
}

// Liste der Mails abrufen
function pop3_getsubjectlist( $handle, $messagelist_arr, $quit_handle )
{
    // RETURN ARRAY GET_MESSAGELIST
    $subjectlist_arr =     array( 0 => array( "message_nr" => FALSE, "message_from" => FALSE, "message_subject" => FALSE ) );

    $i = 0;
    $j = 0;
    while( $message_nr = $messagelist_arr[ $i ][ "message_nr" ] )
    {
        fputs( $handle, "TOP $message_nr 0rn" );
        $list_return = pop3_wait4result( $handle );
        if( strstr( $list_return, "+OK" ) )
        {
            $subjectlist_arr[ $j ][ "message_nr" ] = $message_nr;
            while( $header_return = fgets( $handle ) )
            {
                if( substr( $header_return, 0, 1 ) != "." )
                {
                    $header_return_arr = explode( ": ", $header_return, 2 );
                    if( $header_return_arr[ 0 ] == "From" )
                        $subjectlist_arr[ $j ][ "message_from" ] = $header_return_arr[ 1 ];
                    if( $header_return_arr[ 0 ] == "Subject" )
                        $subjectlist_arr[ $j ][ "message_subject" ] = $header_return_arr[ 1 ];
                }
                else break;
            }
            $j++;
        } else break;
        $i++;
    }

    // Handle schließen
    if( $quit_handle )
    {
        fputs( $handle, "QUITrn" );

        $handle = fgets( $handle );
    }

    return $subjectlist_arr;
}

// Läd Message vom POP3 Server, Body und Header getrennt
function pop3_getmessage( $handle, $message_nr, $quit_handle )
{
    $message_arr =    array( "message_nr" => FALSE, "message_header" => FALSE, "message_body" => FALSE );
    $header_complete = FALSE;

    fputs( $handle, "RETR $message_nrrn" );
    $retr_return = pop3_wait4result( $handle );
    if( strstr( $retr_return, "+OK" ) )
    {
        $message_arr[ "message_nr" ] = $message_nr;
        while( $retr_return = fgets( $handle ) )
        {
            if( substr( $retr_return, 0, 1 ) != "." )
            {
                // Erste Leerzeile Kennzeichen für Header Ende
                if( $retr_return == "rn" || $retr_return == "nr" )
                    $header_complete = TRUE;
                // Header und Body laden
                if( $header_complete )
                {
                    $message_arr[ "message_body" ] .= $retr_return;
                }
                else
                {
                    $message_arr[ "message_header" ] .= $retr_return;
                }
            }
            else break;
        }
    }

    // Handle schließen
    if( $quit_handle )
    {
        fputs( $handle, "QUITrn" );
        $handle = fgets( $handle );
    }

    return $message_arr;
}

// Verbindung beenden
function pop3_quit( $handle )
{
    fputs( $handle, "QUITrn" );
    $handle = fgets( $handle );
    return TRUE;
}

// Übersetze STAT-Array in lesbares Format
function pop3_parse_stat( $stat_array )
{
    // RETURN ARRAY PARSE_STAT
    $parse_stat_arr =     array(    "mails" => FALSE,
                    "size" => FALSE );

    // Nur parsen, wenn Handle geöffnet, oder erfolgreich geschlossen
    if( $stat_array[ "handle" ] )
    {
        $parse_arr = explode( " ", $stat_array[ "status" ] );
        $parse_stat_arr[ "mails" ] = $parse_arr[ 1 ];
        $parse_stat_arr[ "size" ] = $parse_arr[ 2 ];
    }
    return $parse_stat_arr;
}

$pop_check = pop3_getstat( "domain.tld", 110, "user", "passwort", 1, FALSE );
print "Handle Result: " . $pop_check[ "handle" ] . "<br>";
print "Init Result: " . $pop_check[ "init" ] . "<br>";
print "User Result: " . $pop_check[ "user" ] . "<br>";
print "Pass Result: " . $pop_check[ "pass" ] . "<br>";
print "Status Result: " . $pop_check[ "status" ] . "<br><br>";

$pop_status = pop3_parse_stat( $pop_check );
print "Mails in Mailbox: " . $pop_status[ "mails" ] . "<br>";
print "Größe der Mails: " . $pop_status[ "size" ] . " octets<br><br>";

$msg_list = pop3_getmessagelist( &$pop_check[ "handle" ], FALSE );
$i = 0;
while( $message_nr = $msg_list[ $i ][ "message_nr" ] )
	{
	$message_size = $msg_list[ $i ][ "message_size" ];
	print "Nachricht $message_nr Größe $message_size octets<br>";
	$i++;
	}
print "<br>";

$subject_list = pop3_getsubjectlist( &$pop_check[ "handle" ], $msg_list, FALSE );
$i = 0;
while( $message_nr = $subject_list[ $i ][ "message_nr" ] )
	{
	$message_from = htmlspecialchars( $subject_list[ $i ][ "message_from" ] );
	$message_subject = htmlspecialchars( $subject_list[ $i ][ "message_subject" ] );
	print "Nachricht $message_nr von $message_from mit Betreff <a href="./script.php?get_message=$message_nr">$message_subject</a><br>";
	$i++;
	}
print "<br><hr width="100%">";

while($z <= 1)
	{
	$message = pop3_getmessage( &$pop_check[ "handle" ], $z, FALSE );
	print "Nachricht #$message_nr:<br>";
	print "<b>Mail-Header:</b><br>" . str_replace( "n", "<br>", htmlspecialchars( $message[ "message_header" ] ) ) . "<br>";
	print "<b>Mail-Body:</b><br>" . str_replace( "n", "<br>", htmlspecialchars( $message[ "message_body" ] ) ) . "<br><hr>";
	#pop3_delmess('$z');
	$z++;
	}


// Verbindung beenden
pop3_quit( &$pop_check[ "handle" ] );
exit;
Also das speichern der Mails in einer SQL-Datenbank ist absolut nicht das Problem... Sowas mach ich ja ständig. Was mich allerdings wirklich um Kopf und Kragen bringt, ist:

a) die Sache, dass jede abgerufene Mail auch gelöscht werden muss
b) die Sache, wie ich aus dem gesamten Text der Mail etwas lesbares hinbekomme


Also benötige ich einmal die Möglichkeit im obigen Script, eine Mail zu löschen, damit ich das in einen CronJob mit einbinden kann. Ausserdem habe ich etwas von einer PHP-Mail-Classe gehört, die wohl aus dem gegebenen Mail-Text mit Header usw. eine vernünftige Mail gebastelt bekommt.


Für Eure Hilfe wäre ich sehr dankbar.
static
Posts: 437
Joined: 2002-10-27 19:56
Location: Schweiz

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by static »

Hi

Also eigentlich "nur" ein php Problem oder?

Für 1. gibts imap_delete() und imap_expunge(), die kannst du auch für pop3 verwenden. -> Manual

Für 2. gibts eine mailparse Klasse, für die du aber anscheinend php mit --enable-mailparse kompilieren musst. -> Manual

Wobei es dafür wohl auch Alternativen geben wird, vielleicht mal googlen.

Ansonsten kannst du dir vielleicht noch b1gMail ansehen. Das macht glaube ich genau das was du willst (Catch-All Adresse, Verwaltung per PHP) und lässt sich über Smarty anpassen.
(Über die Umsetzung kann ich nichts sagen, habe es selbst nie genutzt/installiert.)

.static
getmuzic.de
Posts: 6
Joined: 2006-10-15 01:03

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by getmuzic.de »

Also die IMAP-Funktion kommt bei dem Script, dass ich bereits hier habe, gar nicht in Frage. Ich habe bereits mit IMAP experimentiert, kam jedoch absolut nicht auf das Postfach drauf. Und ich habe einige Foren und Dokumentationen nach IMAP durchsucht. Habe auch haufenweise Lösungsansätze gefunden, aber keine funktionierte.

Und da ich mich mit der Funktion fsock überhaupt garnicht auskenne, habe ich gehofft, hier wäre jemand, der mir das Script so erweitern kann, dass ein Klick genügt um eine Mail zu löschen.

Ich habe mich mit Mails über PHP noch nicht wirklich großartig beschäftigt, da wie oben schon geschrieben, alle Versuche per IMAP auf POP3 zuzugreifen gescheitert sind.

Also möchte ich bitten, dass mir jemand das Script erweitert, so dass ich eMails ganz einfach per Klick löschen kann.

Und die Sache mit dem Umwandeln sollte eigentlich relativ einfach sein. Dazu bräuchte ich nur eine bereits geschriebene Function, die ich in das Script einbinde und mit $var = function($mail); einbinde.
flo
Posts: 2223
Joined: 2002-07-28 13:02
Location: Berlin

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by flo »

getmuzic.de wrote:Also die IMAP-Funktion kommt bei dem Script, dass ich bereits hier habe, gar nicht in Frage. Ich habe bereits mit IMAP experimentiert, kam jedoch absolut nicht auf das Postfach drauf. Und ich habe einige Foren und Dokumentationen nach IMAP durchsucht. Habe auch haufenweise Lösungsansätze gefunden, aber keine funktionierte.
Für IMAP mit PHP muß zwingend die imap-Biobliothek mit einkompiliert sein - ich hab drei durchprobiert, bis eine lief, der Speicherbedarf ist definitiv erhöht und somit laufen die IMAP-Erweiterungen bei mir auch nur für Webmail. Das Installationsproblem müsste aber mit Binärpaketen zu umgehen sein.

Soweit ich das im Kopf habe, ist die Zuordnung "neu bzw. ungelesen" bei POP3 Verbinungs- bzw. Clientseitig - d.h. Du kannst schon eine Mail per "DELE <nummer>" löschen - nur kann die Nummer bei der nächsten Verbindung zu einer anderen Mail gehören - wie gesagt, bei POP3 stecke ich nicht mehr allzusehr drin, benutze seit füf Jahren nur noch IMAP.

flo.
getmuzic.de
Posts: 6
Joined: 2006-10-15 01:03

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by getmuzic.de »

Hmmm... Wie kann ich denn bei mir diese IMAP-Funktion ans laufen bekommen???
Was für Info's braucht Ihr, um mir zu sagen, was ich machen muss, damit IMAP funktioniert?
flo
Posts: 2223
Joined: 2002-07-28 13:02
Location: Berlin

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by flo »

apt-get install php(...irgendwas...)imap

???

Da wird es in der Regel ein Paket Deines Distributors geben - wie gesagt apt würde sich da anbieten, yast ...

oder alternativ, wenn Du php selber baust:

http://www.washington.edu/imap/

flo.
getmuzic.de
Posts: 6
Joined: 2006-10-15 01:03

Re: POP3 Postfach über PHP auslesen und in Datenbank speichern

Post by getmuzic.de »

Also wenn ich eine PHP-Datei anlege, mit dem Inhalt:

Code: Select all

echo phpinfo();
Dann gibt mir das Script bei IMAP folgendes aus:

imap
IMAP c-Client Version 2004
SSL Support enabled


Also installiert ist IMAP, oder liege ich da falsch?