Search code examples
phpdelphidelphi-xeindy

Upload a file to web server Delphi + php


i am working on a program and i need to upload a 'log.txt' to a webserver.. by http

i've searched and got to this :-

Delphi XE :

procedure TForm1.Button1Click(Sender: TObject);
begin
idhttp1.Post('http://127.0.0.1/GET2.php', 'C:\Users\Someone\Desktop\log.txt')
end;

php :-

<?php
$uploaddir = "uploads/";
$uploadfile = $uploaddir . basename( $_FILES['file']['name']);

if(move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile))
{
  echo "The file has been uploaded successfully";
}
else
{
  echo "There was an error uploading the file";
}
?>

but no files being uploaded

thanks for your help


Solution

  • Read the PHP documentation.

    Your PHP code is using $_FILES, which expects the client to post an HTML webform in MIME multipart/form-data format:

    Handling file uploads > POST method uploads

    PHP is capable of receiving file uploads from any RFC-1867 compliant browser.

    RFC 1867 Form-based File Upload in HTML

    But that format is not what your application is actually posting, though. It is simply posting the raw file content as-is with no MIME metadata to describe the file. That is why your PHP code is not working.

    To post a multipart/form-data HTML webform using TIdHTTP.Post(), you have to use the TIdMultipartFormDataStream class, eg:

    uses
      ..., IdHTTP, IdMultipartFormDataStream;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      PostData: TIdMultipartFormDataStream;
    begin
      PostData := TIdMultipartFormDataStream.Create;
      try
        PostData.AddFile('file', 'C:\Users\Someone\Desktop\log.txt');
        idhttp1.Post('http://127.0.0.1/GET2.php', PostData)
      finally
        PostData.Free;
      end;
    end;
    

    Alternatively, PHP also supports HTTP PUT requests for file uploads:

    Handling file uploads > PUT method support

    procedure TForm1.Button1Click(Sender: TObject);
    var
      FS: TFileStream;
    begin
      FS := TFileStream.Create('C:\Users\Someone\Desktop\log.txt', fmOpenRead or fmShareDenyWrite);
      try
        idhttp1.Put('http://127.0.0.1/log.txt', FS);
      finally
        FS.Free;
      end;
    end;
    
    <?php
    /* PUT data comes in on the stdin stream */
    $putdata = fopen("php://input", "r");
    
    /* Open a file for writing */
    $fp = fopen("log.txt", "w");
    
    /* Read the data 1 KB at a time
       and write to the file */
    while ($data = fread($putdata, 1024))
      fwrite($fp, $data);
    
    /* Close the streams */
    fclose($fp);
    fclose($putdata);
    ?>