【问题标题】:Upload a file to web server Delphi + php上传文件到网络服务器 Delphi + php
【发布时间】:2016-01-19 18:14:30
【问题描述】:

我正在开发一个程序,我需要通过 http 将“log.txt”上传到网络服务器。

我已经搜索过了:-

德尔福 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";
}
?>

但没有上传文件

感谢您的帮助

【问题讨论】:

    标签: php delphi delphi-xe indy


    【解决方案1】:

    阅读 PHP 文档。

    您的 PHP 代码正在使用 $_FILES,它希望客户端以 MIME multipart/form-data 格式发布 HTML 网络表单:

    Handling file uploads > POST method uploads

    PHP 能够从任何符合 RFC-1867 的浏览器接收文件上传。

    RFC 1867 Form-based File Upload in HTML

    但是,这种格式并不是您的应用程序实际发布的格式。它只是按原样发布原始文件内容,没有 MIME 元数据来描述文件。这就是您的 PHP 代码无法正常工作的原因。

    要使用TIdHTTP.Post() 发布multipart/form-data HTML 网络表单,您必须使用TIdMultipartFormDataStream 类,例如:

    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;
    

    另外,PHP 还支持 HTTP PUT 文件上传请求:

    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);
    ?> 
    

    【讨论】:

    • 这就回答了我的问题,解决了。
    • @David Heffernan :那时我没有接受答案的特权!先生,您今天过得不好吗?你对我在 * 中发布的所有内容投了反对票,并给了我政治风格的执行。
    • 您可以随时接受答案。感谢您这样做。
    • 嗨,我尝试了这些代码并且它正在工作。但输出始终是 log.txt 有没有办法使输出文件遵循原始源名称?
    • @Miranachan 当使用POST$_FILES 时,源文件名在$_FILES['fieldName']['name'] 中,每个the documentation 我在我的答案中链接到。当PUTfopen("php://input")一起使用时,源文件名在$_SERVER['REQUEST_URI']中,你必须解析出文件名,见Get only filename from url in php without any variable values which exist in the url