Delphi indy调用php脚本

3

我在我的服务器上有一个 PHP 脚本,它非常简单,因为它只有一个任务:将两个数据存储到 SQL 数据库中。

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

如果您在浏览器中打开此URL,将添加一行到类似于以下内容的SQL表中: enter image description here 我也想使用FireMonkey将数据存储到数据库中,并在应用程序中放置了两个TEdits和一个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;
中的代码存在问题,无法运行。有什么想法吗?

据我所知,根本不需要捕获任何异常。只需删除try/except即可。第一个代码块有什么问题吗?您不想在UI线程中运行它吗? - David Heffernan
好的,我将删除try/except。如果它在UI线程上运行需要仅需一秒钟或更短的时间,那么这也无妨,但是如果有x个问题并且连接变慢,UI可能会冻结。我不确定是使用任务并让它并行运行还是只是放置一个标签,上面写着“正在处理...”。 - Raffaele Rossi
如果您想保持用户界面的响应性,请在任务或线程中运行它。 - David Heffernan
为什么你要使用一个ITask的动态数组?难道你不能简单地运行一个Task吗? - Alberto Miola
1个回答

6

首先,当你在浏览器中输入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可能是多余的,可以省略。
至于互联网连接问题——通常情况下,你应该在任务/线程中执行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 表中的一行)... - Raffaele Rossi
1
@RaffaeleRossi 嗯,是的,我非常确定。是的,POST可以用来发送参数,但您没有正确使用POST,而且您所说的关于您的脚本与浏览器一起工作的内容意味着它与GET一起工作,而不是POST。您可以使用像Wireshark或Fiddler这样的数据包嗅探器来验证。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接