Delphi dış php komut dosyası çalıştırma

2 Cevap php

Tamam - sending an email using a php script hakkında benim önceki soruya devamı budur. Ben şimdi PEAR posta göndermek için kullanıyorum. PHPEMail.php: i kullanma php komut biri aşağıdaki (başarmış yalnız yürütülen,) olduğunu

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

$from = "FromName <FromName@SomeAddress.com>";
$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>");
 }
?>

Ben şimdi winsock kullanarak bazı değişkenler geçirerek, Delphi bu komut dosyasını (PHPEMail.php) yürütmek gerekiyor. Bu kod ile gidiyorum - şimdi başarıyla kadar değil:

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]

Ben arıza web sunucusuna gönderilir "TheData" olduğundan eminim. PHP komut dosyası sadece tetiklenir. Herkes ne yanlış gidiyor bir fikriniz var mı?

(Not: i üçüncü parti bileşenleri istemiyorum, winsock kullanmak istediğiniz hakkında 12ko sunucu, ağırlık ve tam kod, bazı donanım gömülmüş olması destinated edilir.).

SEE FINAL CODE AT END.


I sunucu günlüğüne üzerinde POST göremiyordu çünkü benim kodunda bazı iyileşme (artı bazı hata mesajı) yaptık. ŞİMDİ sunucunun günlük yani, her zamanki kimliği ve zaman artı kelimenin lettre "P" ... muhtemelen ilk harfi 'POST' (Veri gönderiliyor ...) gönderilen paketlerin bazı iz gösterir. Ben böylece '(Gönder)' komutu araştırmak gerekir. (Delphi 2009 tarihinde değilim). Ben winsock veya send komutu hiçbir hatası alıyorum.

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 komut POST bekliyor:

<?php
require_once "Mail.php";

$from = "name <name@tatata.com>";
$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>");
 }
?>

2 Cevap

İlk HTTP satırın ikinci belirteç mutlak bir URL yolu olması gerekir. Bu bir bölü çizgisi ile başlamak gerekiyor.

POST /PHPEMail.php HTTP/1.0

Içerik türü diyor gibi de, gönderdiğiniz veri gerçekten URL kodlanmış olmasını sağlamak için çaba sarf etmeliyiz. Karakterler 10 ve 13 bir URL geçerli karakter değildir. Ayrıca okuyorsunuz metin dosyasındaki tüm karakterleri dikkate almak gerekir:

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

Ben sunucudan yanıt okumuyorsun fark. Olduğunu göz ardı etmeyin. Bazen neyin yanlış olduğunu söyleyebilir. Ben de sunucu günlükleri kod çalıştırmayı denediniz oluştu dedi ne hiçbir söz gördüm.

Sen yol boyunca bu gibi daha fazla hata yapmaya uğrarsınız. ICS, örneğin Indy, sizin için bu tür şeyler işleyen bir kitaplık kullanmayı düşünün, ya da Synapse. Eğer gerçekten yoksa HTTP yeniden uygulamak gerekmez. Eğer gerçekten üçüncü taraf kod istemiyorsanız Ve, Windows yerleşik malzeme kullanarak (ya da birinci parti?) Ikinci parti kodu düşünün. KB 165298 URL-kodlanmış form isteği göndermek için InternetConnect , HttpOpenRequest , and HttpSendRequest kullanarak kısa bir örnek vardır.

Ben Delphi kodu gördüğünüz gibi, e-posta tüm bilgileri tek bir değişken içine paketlenmiş olmuştur, ancak php komut nasıl sizin birçok php değişkenler geçmek? Eğer php komut her değişkeni (hedef adresi, konu, mail gövdesi vb) geçmesine ayrıştırmak / açmak için var. (Geçerli php komut dosyası pek çok $ _posts vardır, ama Delphi kod sadece 1 gerçek mesajı alır.)

Aşağıda bir php script benim çalışma koddur.

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;

Bir # 13 # 10.

Bir diğer önemli şey "link = 'olduğu;. Ben sadece 1 değişken yolluyorum beri yolluyorum verileri tutan / aldığında benim php komut değişken adı olduğunu ve hiçbir php ayrıştırma gerekli, e-komut değil, Bu yüzden burada benim php kod yapıştırın vermedi.

Ben açıkça yapılan umuyoruz :)