2009-05-26 11 views
0

Ok - das ist in Fortsetzung meiner früheren Frage über sending an email using a php script. Ich verwende jetzt PEAR, um die Mail zu senden. Der PHP-Skript Ich benutze ist die folgende (erfolgreich, wenn sie allein ausgeführt): PHPEMail.phpAusführen eines externen PHP-Skript von Delphi

<?php 
require_once "Mail.php"; // Pear Mail.php 

$from = "FromName <[email protected]>"; 
$to = $_POST["destination"]; // destination 
$subject = "Hello You!"; 
$body = $_POST["nicebody"]; // body of text sent 
$host = "ValidServerName"; 
$username = "User";   // validation at server  
$password = "Password";  // validation at server 

$headers = array ('From' => $from, 
    'To' => $to, 
    'Subject' => $subject); 
$smtp = Mail::factory('smtp', 
    array ('host' => $host, 
    'auth' => true, 
    'username' => $username, 
    'password' => $password)); 

$mail = $smtp->send($to, $headers, $body); 

if (PEAR::isError($mail)) { 
    echo("<p>" . $mail->getMessage() . "</p>"); 
} else { 
    echo("<p>Message successfully sent!</p>"); 
} 
?> 

ich jetzt dieses Skript (PHPEMail.php) von Delphi ausführen muß, einige Variablen vorbei, unter Verwendung von Winsock. Ich bin mit diesem Code gehen - was bisher wurde nicht erfolgreichen up:

Procedure SendEmail; 
var 
    WSADat:WSAData; 
    SomeText:TextFile; 
    Client:TSocket; 
    Info,TheData,Lina,Nicebody:String; 
    SockAddrIn:SockAddr_In; 
begin 
    try 
    if not FileExists(Log) then exit;  
    AssignFile(SomeText, Log);    // try to open log, assigned to SomeText 
    Reset(SomeText);      // Reopen SomeText for reading 
    while not Eof(SomeText) do 
    begin 
     ReadLn(SomeText, Lina);    //read each line of SomeTextans place it in linha 
     nicebody:=Nicebody+#13#10+Lina;  // nicebody = all line red from SomeText 
    end; 
    CloseFile(SomeText);     // SomeText is closed 
    DeleteFile(PChar(Log));    // log is deleted 
// 
    WSAStartUp(257,WSADat); 
    Client:=Socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
    SockAddrIn.sin_family:=AF_INET; 
    SockAddrIn.sin_port:=htons(80); 
    SockAddrIn.sin_addr.S_addr:=inet_addr('66.66.66.66'); // server IP 
    if Connect(Client,SockAddrIn,SizeOf(SockAddrIn))=0 then begin 
     Info:='destination='+EmailDestAddressFromIni + '' +'Nicebody='+Nicebody; 
     TheData:='POST PHPEMail.php HTTP/1.0'     +#13#10+ 
      'Connection: close'        +#13#10+ 
      'Content-Type: application/x-www-form-urlencoded'+#13#10+ 
      'Content-Length: '+IntToStr(Length(Info))  +#13#10+ 
      'Host: someEmailHostAddress'       +#13#10+ 
      'Accept: text/html'        +#13#10+#13#10+ 
       Info           +#13#10; 
     Send(Client,Pointer(TheData)^,Length(TheData),0); 
     end; 
    CloseSocket(Client); 
    except 
    exit; 
    end; 
end; 

[... more code not related] 

Ich bin mir ziemlich sicher, dass der Fehler in „theData“, dass an den Webserver gesendet wird. Das PHP-Skript wird nicht ausgelöst. Hat jemand eine Idee, was schief läuft?

(Hinweis: Ich möchte Winsock verwenden, ich möchte keine Komponenten von Drittanbietern. Der vollständige Code, der ein Server ist, wiegt etwa 12ko und ist in einigen Hardware eingebettet werden).

SIEHE FINALCODE AM ENDE.


Weil ich nicht die Post auf dem Server-Log, ich habe in meinem Code einige Verbesserungen gemacht sehen konnte (plus einige Fehlermeldung). JETZT zeigt das Protokoll des Servers eine Spur der gesendeten Pakete an ... das heißt, die übliche ID und Zeit plus das Lettre "P" ... wahrscheinlich der erste Buchstabe des Wortes "POST" (die gesendeten Daten). Ich muss also den 'Send()' Befehl untersuchen. (Ich bin auf Delphi 2009). Ich bekomme keinen Fehler von Winsock oder dem Send-Befehl.

Procedure SendEmail; 

const 
    a = #13#10; 

var 
    WSAData:TWSAData; 
    Texto:TextFile; 
    ClientSocket :TSocket; 
    Info,Data,Lina,Contenu:String; 
    host:SockAddr_In; 
    i_result:Integer; 

begin 
    try 
    if not FileExists(Log) then exit;  
    AssignFile(Texto, Log);  
    Reset(Texto); // Reopen texto for reading 
    while not Eof(Texto) do 
    begin 
     ReadLn(Texto, Lina); //read each line of texto and place it in lina 
     Contenu:=Contenu+#13#10+Lina; // contenu is all lines of texto 
    end; 
    CloseFile(Texto); // close texto 
    DeleteFile(PChar(Log)); // delete log 


    // Initialize Winsock 
    i_result := WSAStartUp(257,WSAData); 
    if (i_Result <> NO_ERROR) then 
    begin 
    MessageBox(0,'Initialization of winsock failed.','Error',MB_OK Or MB_ICONERROR); 
    Exit; 
    end; 

    // Create a SOCKET for connecting to server 
    ClientSocket := Socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
    If ClientSocket = INVALID_SOCKET Then 
    begin 
    MessageBox(0,'ServerSocket creation failed.','Error',MB_OK Or MB_ICONERROR); 
    WSACleanUp; 
    Exit; 
    end; 

    // The sockaddr_in structure specifies the address family, 
    // IP address, and port of the server to be connected to. 
    host.sin_family:=AF_INET; 
    host.sin_port:=htons(80); 
    host.sin_addr.S_addr:=inet_addr('77.66.66.66'); 

    // Connect to server. 
    i_result:= Connect(ClientSocket,host,SizeOf(host)); 
    if i_result = SOCKET_ERROR then 
    begin 
    MessageBox(0,'Failed to connect to remote computer.','Error',MB_OK Or MB_ICONERROR); 
    WSACleanUp; 
    Exit; 
    end 
    else 
    begin 

     Info := 'destination=' + UrlEncode(CFG.Email) + '&' + 'contenu=' + UrlEncode(contenu); 
     Data:='POST /pearemail.php HTTP/1.0'     +#13#10+ 
      'Connection: close'        +#13#10+ 
      'Content-Type: application/x-www-form-urlencoded'+#13#10+ 
      'Content-Length: '+IntToStr(Length(Info))  +#13#10+ 
      'Host: mail.tatata.com'       +#13#10+ 
      'Accept: text/html'        +#13#10+#13#10+ 
       Info+#13#10; 

     // Send buffer 
     i_result := Send(ClientSocket,Pointer(Data)^,Length(Data),0); 
     if (i_result = SOCKET_ERROR) then 
     MessageBox(0,'Failed to send to remote computer.','Error',MB_OK Or MB_ICONERROR); 
     closesocket(ClientSocket); 
     WSACleanup; 
     Exit; 

    end; 
     // shutdown the connection since no more data will be sent 
     i_result:= shutdown(ClientSocket, SD_SEND); 
     if (i_Result = SOCKET_ERROR) then 
     MessageBox(0,'Shutdown failed.','Error',MB_OK Or MB_ICONERROR); 
     closesocket(ClientSocket); 
     WSACleanup(); 
     Exit; 

    except 
    exit; 
    end; 
end; 

pearemail.php Skript für die POST warten:

<?php 
require_once "Mail.php"; 

$from = "name <[email protected]>"; 
$to = $_POST["destination"]; 
$subject = "Number 2!"; 
$body = $_POST["contenu"]; 
$host = "mail.server.com"; 
$username = "user"; 
$password = "password"; 

$headers = array ('From' => $from, 
    'To' => $to, 
    'Subject' => $subject); 
$smtp = Mail::factory('smtp', 
    array ('host' => $host, 
    'auth' => true, 
    'username' => $username, 
    'password' => $password)); 

$mail = $smtp->send($to, $headers, $body); 

if (PEAR::isError($mail)) { 
    echo("<p>" . $mail->getMessage() . "</p>"); 
} else { 
    echo("<p>Message successfully sent!</p>"); 
} 
?> 
+0

Seien carefaul, Ihr pHP-Code von Spammern missbraucht werden wird, wenn Sie es online den Weg legen sie ist. – julioc

Antwort

2

Das zweite Zeichen der ersten HTTP Linie muss ein absoluter URL-Pfad sein. Es muss mit einem Schrägstrich beginnen.

 
POST /PHPEMail.php HTTP/1.0 

Sie sollten auch einige Anstrengungen unternehmen, um sicherzustellen, dass die Daten, die Sie wirklich URL-kodiert ist senden, da der Content-Type sagt, es ist. Die Zeichen 10 und 13 sind keine gültigen Zeichen in einer URL. Sie müssen auch alle Zeichen in der Textdatei, die Sie gerade lesen beachten:

Info := 'destination=' + UrlEncode(EmailDestAddressFromIni) + 
    '&' + 'Nicebody=' + UrlEncode(Nicebody); 

ich feststellen, dass Sie nicht die Antwort vom Server zu lesen. Ignorier das nicht. Manchmal kann es Ihnen sagen, was falsch ist. Ich habe auch nicht erwähnt, was der Server protokolliert hat, als er versucht hat, den Code auszuführen.

Sie sind verpflichtet, mehr Fehler wie diese auf dem Weg zu machen. Erwägen Sie, eine Bibliothek zu verwenden, die diese Art von Aufgaben für Sie erledigt, z. B. Indy, ICS oder Synapse. Implementieren Sie HTTP nicht erneut, es sei denn, Sie müssen es wirklich tun. Und wenn Sie wirklich keinen Code von Drittanbietern möchten, sollten Sie den Code von Drittanbietern in Betracht ziehen (oder handelt es sich um Erstanbieter?), Indem Sie die in Windows integrierten Funktionen verwenden. KB 165298 enthält ein kurzes Beispiel für die Verwendung von InternetConnect, HttpOpenRequest und HttpSendRequest zum Veröffentlichen einer URL-codierten Formularanforderung.

+0

Danke. Das Serverfehlerprotokoll sagt nichts - nicht sogar eine Verbindung zeigt! Sollte ich chr 10 und 13 durch etwas
ersetzen? Ich habe Indy, ICS und Synapse versucht, jedes Ergebnis in einem Server, der mehr als 600ko ist - das ist viel zu viel Sünde für mich Der gesamte Server wird in eine Ressource gestellt. Der tatsächliche Code ist ungefähr 12-20ko max. Ich werde einen Blick auf KB165298 werfen. – volvox

+0

Allerdings weiß ich, dass es verbindet. Hinzufügen einer ShowMessage zu einem Zeitpunkt nach "Wenn verbinden" kann ich die gesendeten Daten lesen, dh die Ziel-E-Mail und NiceBody (die Daten). TheData sieht auf den ersten Blick gut formatiert aus. – volvox

+0

Ich denke, die Rückgabe und Feedline für TheData sind in Ordnung, aber ich muss Beispiele finden. NiceBody selbst (Nachricht gesendet) ist wirklich HTML-codiert. – volvox

2

Wie ich aus Ihrem Delphi-Code sehe, wurden alle Informationen der E-Mail in eine Variable gepackt, aber in Ihrem PHP-Skript, wie übergeben Sie Ihre vielen PHP-Variablen? Sie müssen es entpacken/analysieren, um jede Variable (Zieladresse, Betreff, Mail-Nachricht usw.) in Ihrem PHP-Skript zu übergeben.(In Ihrem aktuellen PHP-Skript gibt es viele $ _posts, aber es erhält nur 1 tatsächlichen Beitrag von Delphi-Code.)

Unten ist mein Arbeitscode zu einem PHP-Skript.

result := 'POST /index.php HTTP/1.1' + 
a + 'Host: somehost.com' + 
a + 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080406 K-Meleon/1.1.5' + 
a + 'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5' + 
a + 'Accept-Language: en-us,en;q=0.5' + 
a + 'Accept-Encoding: gzip,deflate' + 
a + 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' + 
a + 'Keep-Alive: 300' + 
a + 'Connection: keep-alive' + 
a + 'Referer: http://somehost.com/index.php' + 
a + 'Content-Type: application/x-www-form-urlencoded' + 
a + 'Content-Length: 73' + a + 
a + 'link=' + MyHttpEnCodedStrData + a + a; 

a ist # 13 # 10.

Eine andere wichtige Sache ist "link = '; es ist der Variablenname in meinem PHP-Skript, der die Daten, die ich sende, empfängt/hält. Da ich nur 1 Variable sende, und es ist kein E-Mail-Skript, nein pHP-Parsing erforderlich, so dass ich nicht meinen pHP-Code einfügen hier.

Hoffe, dass ich deutlich gemacht, :)

+0

Er hat Info mit zwei Querystring-Parametern, Ziel und NiceBody gefüllt. Er ließ das Ampersand weg, das sie trennen sollte. PHP kann URL-codierte Postdaten parsen, so dass die Parameter in $ _POST ['destination'] und $ _POST ['nicebody'] aufgeteilt werden. –

+0

Mein erster Versuch bei Info war tatsächlich: Info: = 'Ziel =' + Email + '& NiceBody =' + NiceBody; Ich habe auch versucht (avars Vorschlag): TheData: = 'POST/phpemail.php HTTP/1.0 '+ a +' Verbindung: schließen '+ a +' Inhaltstyp: application/x-www-form-urlencoded '+ a +' Inhaltslänge: '+ IntToStr (Länge (Email) + Länge (NiceBody)) + a + 'Host: Serverhostname' + a + 'Akzeptieren: text/html' + a + 'Ziel =' + E-Mail + a + 'NiceBody =' + NiceBody + a + a; Senden (Client, Zeiger (TheData) ^, Length (TheData), 0); Noch einmal, Daten werden gesendet (lesen Sie auf Sniffer für TCP-Server Hostname), aber immer noch keine Interaktion mit dem PHP-Skript. – volvox

+0

Ich werde versuchen, Ihren PHP-Code mit meinem Delphi-Code und lassen Sie es wissen. später – avar

Verwandte Themen