PHP sockets - simple POP3
-
class CMail{ var $fp; var $fp_open; var $fp_typ; var $fp_cmd; var $fp_output; function CMail(){ $this->fp_output = array(); } function connect_pop3($host){ $this->fp = pfsockopen($host, 110, $errno, $errstr, 10); if(!$this->fp){ echo($errstr." (".$errno.")<br>"); $this->fp_open = false; }else{ $this->fp_open = true; $this->fp_typ = "POP3"; $this->fp_cmd = array("USER","PASS","LIST","STAT","RETR","QUIT"); } } function close(){ fclose($this->fp); } function cmd($cmd_line){ $cmd = split(" ",$cmd_line); if(in_array($cmd[0],$this->fp_cmd)){ fwrite($this->fp,$cmd_line."\r\n",4096); array_push($this->fp_output,$this->___readline()); }else{ echo("command [".(strtoupper($cmd[0]))."] is not supported by ".$this->fp_typ); } } function cout(){ for($i=0; $i<count($this->fp_output); $i++){ echo("<b>LINE ".($i + 1).":</b> ".$this->fp_output[$i]."<br>"); } } function ___readline(){ $data = ''; while(!feof($this->fp) && is_resource($this->fp)){ $data .= fgets($this->fp, 4096); } return $data; } } $myMail = new CMail(); $myMail->connect_pop3("mail.XXXXXXX.ch"); $myMail->cmd("USER XXXXXXX.ch"); $myMail->cmd("PASS XXXXXXX"); $myMail->cmd("RETR 1"); $myMail->cout(); $myMail->close();
script hängt sich auf da anscheinend feof beim command retr 1 nicht mehr funktioniert, weiss jemand warum? müsste doch eigentlich gehen!
-
Du willst doch nicht bis EOF lesen, sondern nur, bis Die Mail zuende ist. EOF wäre in diesem Fall der Ende des Streams und der tritt nur ein, wenn die Gegenstelle die Verbindung beendet.
IIRC definiert POP3, daß die Länge der folgenden Mail mit dem initialen +OK in der ersten Antwortzeile zu finden ist. Du musst diese also parsen und dann so lange lesen, bis die gewünschte Länge erreicht ist.Übrigens: Warum benutzt Du hier ne persistente Verbindung?
Gruß Jens
-
und wie soll ich die Länge abfragen? Bzw. das Ergebniss vom Server parsen? Das pf ist wohl so reingerutscht ist nur ne fs
-
ich hab immernoch keine Lösung für mein Problem gefunden
-
Hast du denn die Länge ausgelesen, so wie es Sa(n)dman gesagt hatte? Zeig mal den veränderten Code
-
wenn ich wüsste wie ich die Länge bzw. das Ende des Pointer rauskriegen könnte? Einfach binär einlesen klappt net
-
Erstmal nur die erste Zeile mit auslesen (also ohne dein while), dann schauen, was hinter dem +OK steht und eben soviel auslesen - so hatte ich das zumindest verstanden
-
bringt leider nicht viel, da POP3 auch mal multiline auf ne Anfrage antworten kann die sonst nur eine Zeile hätte, bestes Beispiel LIST oder RETR 0. Ich will nicht für jeden command einen switch schreiben. ich möchte einfach so lange einlesen bis das ende des pointers erreicht ist, aber wie?
-
Ich kenn mich da nicht so genau aus, aber bekommst du das mit +OK nicht jedesmal? Falls doch: wo ist dein Problem? Einfach die Zahl dahinter auslesen und dann noch entsprechend dieser Zahl noch den Rest auslesen
-
das bringt mir nicht viel, weil diese methode zu unsicher ist und viel zu viele fehler produziert. ich möchte doch nur wissen wie ich den pointer solange bewegen kann bis das ende der ausgabe erreicht ist
-
Laut Sa(n)dman ist das so direkt wie du es dir wünscht aber nicht möglich
-
es geht nicht mal mit byteweise einlesen und bis auf ein \r\n warten *grml* es hackt
-
Solche Klassen gibt es doch sicher auch schon fertig - vielleicht sowas hier
-
ja aber die klassen haben einfach für jeden command ne eigene funktion, dass ist nicht der sinn eines oo scripts
-
Du kannst die Klassen ja dann noch deinen Wünschen entsprechend anpassen - oder eben nur mal schauen, wie die es dort anstellen
-
wie schon gesagt. es gibt für jeden command in POP3 RFC einfach eine Funktion, was ich recht schlecht gelöst finde. ich frage mich einfach warum das so schwer sein soll den Pointer bis zum Ende des Streams zu bewegen und dann die Abfrage auszuwerten
-
Sa(n)dman schrieb:
EOF wäre in diesem Fall der Ende des Streams und der tritt nur ein, wenn die Gegenstelle die Verbindung beendet.
Es scheint also nicht einfacher zu gehen
-
hier kann einem anscheinend auch nicht geholfen werden
-
Wenn du mit dem was dir gesagt wurde nichts anfangen konntest wohl wirklich nicht...
-
CAres schrieb:
ja aber die klassen haben einfach für jeden command ne eigene funktion, dass ist nicht der sinn eines oo scripts
Dann hast Du den Sinn von OO-Skripten (oder besser von OOD) nicht begriffen. Was Du objektorientiert machen kannst, wäre eine eigene Klasse für den Netzwerkverkehr (also im wesentlichen ein Wrapper über fsockopen() und fgets()) und davon abgeleitet eine weitere Klasse mit je einer Methode für jede Funktionalität des POP3-Protokolls. Davon leitest Du dann wiederum eine Klasse ab, welche die eigentlichen Aufgaben als Methoden beinhaltet, also z.B. Mailbox-Inhalt listen, Mails auslesen, Mails löschen, etc.
Mehr ist unter objektorientierten Gesichtspunkten nicht sinnvoll oder gewünscht. Ganz abgesehen davon ist es, wie ich eingangs schon erwähnte aufgrund der Protokollspezifikation nunmal nicht anders möglich, als jedes Problem getrennt zu betrachten. Dein Ansatz würde bedingen, daß der komplette Befehlssatz des POP3 einen gemeinsamen Aufbau hat, wie es z.B. beim HTTP der Fall ist. In solchen Fällen könntest Du die gewünschte Abstraktion vornehmen, im gegebenen Fall ist das nun aber einfach mal nicht möglich, sondern pures Wunschdenken Deinerseits.
Gruß Jens