【问题标题】:Delphi indy call php scriptDelphi indy调用php脚本
【发布时间】:2016-11-06 22:13:13
【问题描述】:

我的服务器中有一个非常简单的 php 脚本,因为他有一个任务:在 sql 数据库中存储两个数据。

http://mydomain.it/test.php?id=285&numero=504;

如果你在浏览器中打开这个 url,你将在一个如下所示的 sql 表中添加一行

我也希望能够使用 firemonkey 将数据存储在数据库中,并且我在我的应用程序中放置了两个 TEdit 和一个 TButton。单击此代码执行的按钮:

var url: string;
 H: TIdHttp;
 SS: TStringStream;
begin
 url := 'http://mydomain.it/test.php?id='+IntToStr(a)+'&numero='+IntToStr(b);
 H := TIdHttp.Create(nil);
 try
  SS := TStringStream.Create;
  try

   try
    H.Post(url, SS);
   except
    on E:Exception do
    ShowMessage(e.Message);
   end;

  finally
   SS.Free;
  end;
 finally 
  H.Free;
 end;

上面的代码运行良好,因为它只需要 1 秒的时间运行,而且我正在捕获异常(仅用于调试目的)。我有两个主要问题:

  1. 这是我第一次使用 indy,据我了解,这是满足我需要的好方法。我不确定我是否将try-except 放在了正确的位置;是吗?

  2. 如果互联网连接速度很慢怎么办?我应该使用类似下面的代码吗?

代码

var process: array of ITask;
begin

 SetLength(process, 1);

 process[0] := TTask.Create(
  procedure
   var url: string;
    H: TIdHttp;
    SS: TStringStream;
   begin
    url := 'http://mydomain.it/test.php?id='+IntToStr(a)+'&numero='+IntToStr(b);
    H := TIdHttp.Create(nil);
    try
     SS := TStringStream.Create;
     try
      try
        H.Post(url, SS);
       except
        on E:Exception do
        ShowMessage(e.Message);
       end;
     finally
      SS.Free;
     end;
    finally H.Free;
    end;
  end
 );
 process[0].Start;

 TTask.WaitForAll(process);
 Label1.Text := 'done!!';

end;

第 2 节中的代码有一些问题,它不起作用。有什么想法吗?

【问题讨论】:

  • 据我所知,根本不需要捕获异常。只需删除 try/except。第一个代码块有什么问题?你不想在 UI 线程中运行它?
  • 好的,我正在删除 try/except so。如果它在 UI 线程上运行很好,因为它只需要一秒钟或更短的时间来执行,但如果有 x 问题并且连接变慢,UI 可能会冻结。我不确定是使用一个任务并让它并行运行,还是只是贴一个标有“进程...”的标签
  • 如果您想保持 UI 响应,请在任务或线程中运行它
  • 为什么要使用 ITask 的动态数组?你不能简单地运行一个任务吗?

标签: delphi indy


【解决方案1】:

首先,当您在浏览器中输入 URL 时,它会发送 GET 请求,而不是 POST 请求。你应该使用TIdHTTP.Get() 而不是TIdHTTP.Post()

var
  url: string;
  H: TIdHTTP:
begin
  url := 'http://mydomain.it/test.php?id='+IntToStr(a)+'&numero='+IntToStr(b);
  try
    H := TIdHTTP.Create(nil);
    try
      H.Get(url);
      // or:
      // H.Get(url, TStream(nil));
    finally 
      H.Free;
    end;
  except
    on E: Exception do
      ShowMessage(e.Message);
  end;
end;

现在,回答您的问题:

一般来说,您显示的try/except 没问题。我更喜欢将try/finally 放在try/except 中,如上所示,而不是相反。但根据您实际使用代码的位置,try/except 可能是多余的,可以省略。

至于 Internet 连接问题 - 通常,是的,您应该在任务/线程中执行 HTTP 操作,而不是在主 UI 线程中:

begin
  TTask.Create(
    procedure
    var
      url, msg: string;
      H: TIdHTTP;
    begin
      try
        url := 'http://mydomain.it/test.php?id='+IntToStr(a)+'&numero='+IntToStr(b);
        H := TIdHTTP.Create(nil);
        try
          H.Get(url);
          // or:
          // H.Get(url, TStream(nil));
        finally
          H.Free;
        end;
        msg := 'done!!';
      except
        msg := 'error!!';
      end;
      TThread.Queue(nil,
        procedure
        begin
          Label1.Text := msg;
        end;
      );
    end
  ).Start;
end;

【讨论】:

  • 嗯,你确定吗?我认为当您传递一些执行操作的参数时使用 POST 请求(在这种情况下,在 sql 表中添加一行)...
  • @RaffaeleRossi 嗯,是的,我很确定。是的,POST 可用于发送参数,但您没有正确使用POST,并且您所说的脚本在浏览器上工作意味着它可以用于GET,而不是POST。您可以使用像 Wireshark 或 Fiddler 这样的数据包嗅探器来验证这一点。
猜你喜欢
  • 2019-10-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 2013-02-10
  • 2014-06-27
  • 1970-01-01
  • 2012-05-04
  • 2023-04-08
相关资源
最近更新 更多