Entwickler-Ecke

Internet / Netzwerk - Datenbankabfrage via PHP mit Delphi 2005 Personal


dieter1a - Di 29.01.08 16:12
Titel: Datenbankabfrage via PHP mit Delphi 2005 Personal
Hallo,

ich habe mit Blender ein 3D Web-Projekt erstellt und übergebe bisher die daten via .txt an einen Director-Film, der wiederum via PHP mit der Datenbank kommuniziert.
Das klappt zwar, ist aber nicht so ideal, weil die Ausnahmebehandlung bei Director mit Lingo unbefriedigend ist.
Jetzt hat mir ein Admin meines projektbegleitenden Forums Delphi ans Herz gelegt.
Augenscheinlich ist das Ganze mit Delphi 2005 Personal wesentlich komfortabler zu gestalten und ich möchte das Projekt auf Delphi umstellen.
Nachdem ich das Form erstellt hatte fing das erste und wahrscheinlich einzige Problem an.

Ich benötige eine Funktion, die meinen String an die .PHP schickt und einen String zurück bekommt.
Ich habe hier ein Script entdeckt, was aber nicht mit 2005 läuft.
Mein Form habe ich mit Delphi für .NET-Projekte/Windows Forms-Anwendung erstellt.

Hier mal das Script, was ich gefunden habe:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
function SendPostData(Ahttp: TIdHTTP; const AtoURL: Stringconst aParams: TStrings): String;

//Ahttp: Die HTTP Komponente von Indy 8.0 bzw. 9.0
//AtoURL: An diese URL werden die Informationen gesendet
//Result: HTML-Ergebnis (Antwort des Scripts)

Var
  lStream: TMemoryStream; //HTML-Result des PHP-Scripts
  lParams: TStringStream;
  I: Integer;
begin
  Result:='';
  if not Assigned(aHttp) then
    exit;
  lStream := TMemoryStream.create;
  lParams := TStringStream.create('');
  try
    AHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    //Dieser Stream wird letztendlich gesendet
    //Stream mit Werten füllen
    for I:=0 to aParams.Count-1 do
      lParams.WriteString(aParams[I] + '&');
    try
      //Stream an das PHP-Script senden
      AHTTP.Post(AtoURL,
                 lParams,
                 lStream);
    except
      on E: Exception do
        showmessage('Fehler bei der Übertragung: ' + E.Message);
    end;
    SetLength(Result,lStream.Size);
    lStream.Position:=0;
    lStream.ReadBuffer(Result[1],lStream.Size);
  finally
    lParams.Free;
    lStream.Free;
  end;
end;


Möglicherweise ist hier jemand so freundlich und gibt mir einen Tip wie ich das unter 2005 zum laufen bringe.
Ich bedanke mich im schon mal Voraus für die Mühe.

MfG dieter1a


jaenicke - Di 29.01.08 16:30

Willkommen hier im Forum ;-). :welcome:

Die Frage ist, wo das Problem ist, also was kommt für eine Fehlermeldung? Was funktioniert nicht?


dieter1a - Di 29.01.08 16:41

Hallo,

nachdem ich den Code eingefügt hatte und ich wieder nach Design wollte, kam folgende Meldung:

Beim Laden des Dokuments ist ein Fehler aufgetreten. Beheben Sie den Fehler und versuchen Sie, das Dokument erneut zu laden. Die Fehlermeldung lautet:

Der Designer wird für diese Datei nicht angezeigt, weil keine der enthaltenen Klassen entworfen werden kann.

MfG dieter1a


jaenicke - Di 29.01.08 17:01

Diese Meldung ist mir gänzlich unbekannt. Die einzige Ursache, die ich mir vorstellen könnte, wäre, dass der Code an der falschen Stelle eingefügt wurde und Delphi daher die Unit nicht mehr parsen kann.

Am besten postest du mal wo du den Quelltext hingeschrieben hast innerhalb der Unit.


dieter1a - Di 29.01.08 17:09

der Ort ist:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
unit WinForm;

interface

uses
  System.Drawing, System.Collections, System.ComponentModel,
  System.Windows.Forms, System.Data, System.Resources, ShellAPI;

var
  exist:String='3';

function SendPostData(Ahttp: TIdHTTP; const AtoURL: Stringconst aParams: TStrings): String;

//Ahttp: Die HTTP Komponente von Indy 8.0 bzw. 9.0
//AtoURL: An diese URL werden die Informationen gesendet
//Result: HTML-Ergebnis (Antwort des Scripts)

Var
  lStream: TMemoryStream; //HTML-Result des PHP-Scripts
  lParams: TStringStream;
  I: Integer;
begin
  Result:='';
  if not Assigned(aHttp) then
    exit;
  lStream := TMemoryStream.create;
  lParams := TStringStream.create('');
  try
    AHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    //Dieser Stream wird letztendlich gesendet
    //Stream mit Werten füllen
    for I:=0 to aParams.Count-1 do
      lParams.WriteString(aParams[I] + '&');
    try
      //Stream an das PHP-Script senden
      AHTTP.Post(AtoURL,
                 lParams,
                 lStream);
    except
      on E: Exception do
        showmessage('Fehler bei der Übertragung: ' + E.Message);
    end;
    SetLength(Result,lStream.Size);
    lStream.Position:=0;
    lStream.ReadBuffer(Result[1],lStream.Size);
  finally
    lParams.Free;
    lStream.Free;
  end;
end;

type
  TWinForm = class(System.Windows.Forms.Form)
  {$REGION 'Vom Designer verwalteter Code'}
  strict private
    /// <summary>
    /// Erforderliche Designervariable.
    /// </summary>
    components: System.ComponentModel.IContainer;
    Label1: System.Windows.Forms.Label;
    PictureBox1: System.Windows.Forms.PictureBox;
    GroupBox1: System.Windows.Forms.GroupBox;
    RadioButton1: System.Windows.Forms.RadioButton;
    RadioButton2: System.Windows.Forms.RadioButton;
    RadioButton3: System.Windows.Forms.RadioButton;
    RadioButton4: System.Windows.Forms.RadioButton;
    RadioButton5: System.Windows.Forms.RadioButton;
    Button1: System.Windows.Forms.Button;
    Button2: System.Windows.Forms.Button;
    /// <summary>
    /// Erforderliche Methode zur Unterstützung des Designers -
    /// ändern Sie die Methode nicht mit dem Quelltext-Editor
    /// </summary>
    procedure InitializeComponent;
    procedure GroupBox1_Enter(sender: System.Object; e: System.EventArgs);
    procedure TWinForm_Load(sender: System.Object; e: System.EventArgs);
  {$ENDREGION}
  strict protected


jaenicke - Di 29.01.08 17:15

Ach, es ist eine .NET Anwendung, gar keine Win32 Anwendung. Da sieht der Quelltext ja leicht anders aus. Ist das gewollt, dass es eine .NET Anwendung ist? (die auch auf dem PC immer das .NET Framework Runtime Environment erfordert)

Jedenfalls gehören eigene Methoden nicht vor die Deklaration sondern dorthin wo auch die Button-Klick-Methoden erstellt werden automatisch.

Ich arbeite aber so gut wie nicht mit .NET unter Delphi (bzw. wenn, dann per Trial and Error, Delphi an sich kann ich ja^^), sondern nutze dafür andere Sprachen. Deshalb weiß ich nicht, inwiefern der Code dafür angepasst werden muss.
Auf jeden Fall wird Indy dafür benötigt, das bei der Personal aber afaik erst installiert werden muss.


dieter1a - Di 29.01.08 17:20

user profile iconjaenicke hat folgendes geschrieben:
Ach, es ist eine .NET Anwendung, gar keine Win32 Anwendung. Da sieht der Quelltext ja leicht anders aus. Ist das gewollt, dass es eine .NET Anwendung ist? (die auch auf dem PC immer das .NET Framework Runtime Environment erfordert)


Leider ist das alles für mich Neuland.

Wie mache ich denn eine Win32 anwendung?


jaenicke - Di 29.01.08 17:31

Es gibt im Menü Neu den entsprechenden Eintrag (Delphi für Win32 Anwendung oder so ähnlich).

An dieser Stelle weise ich am besten noch auf diesen Crashkurs hin: ;-)
http://crashkurs.christian-stelzmann.de
bzw. für Delphi 2005 eher passend:
http://www.christian-stelzmann.de/artikel/CrashkursReloaded/


dieter1a - Di 29.01.08 17:44

Den crash-kurs habe ich schon gelesen.
Hier mal ein Screeny von meinen Möglichkeiten.


jaenicke - Di 29.01.08 17:47

Wie unter dem zweiten Link im Crashkurs auch steht:
VCL-Formularanwendung ;-)


dieter1a - Di 29.01.08 17:50

Vielen Dank Jaenicke,

mal sehen wie`s damit klappt.

MfG dieter1a


dieter1a - Mi 30.01.08 00:50

Damit kann Delphi scheinbar nichts anfangen: TIdHTTP;

function SendPostData(Ahttp: TIdHTTP; const AtoURL: String; const aParams: TStrings): String;


//Ahttp: Die HTTP Komponente von Indy 8.0 bzw. 9.0

Edit:
Ist das mit Delphi denn wirklich so ein großer Aufwand, eine .PHP an zu sprechen und die Antwort zu extraieren?
Mit Python z.B ist das ein Klacks.


dieter1a - Mi 30.01.08 02:14

Welche Indy Installation muss ich für 2005 Personal auswählen?
http://www.atozed.com/indy/plus/Files.DE.aspx


dieter1a - Mi 30.01.08 14:17

Ich habe mit Hilfe eines Tutorials Indy Installiert.
Leider bekomme ich immer noch Fehlermeldungen.

Zitat:
[Fehler] unitpowertower.pas(31): E2003 Undefinierter Bezeichner: 'TIdHTTP'
[Fehler] unitpowertower.pas(43): E2008 Inkompatible Typen
[Fehler] unitpowertower.pas(48): E2066 Operator oder Semikolon fehlt
[Fehler] unitpowertower.pas(55): E2066 Operator oder Semikolon fehlt
[Fataler Fehler] powertower.dpr(5): F2063 Verwendete Unit 'unitpowertower.pas' kann nicht compiliert werden


Oder kennt jemand einen simpleren Weg eine PHP anzusprechen?


dieter1a - Mi 30.01.08 15:21

Da mir an anderer Stelle erklärt wurde, dass ich erstmal TIdHTTP auf das Form ziehen muss, klappt alles hervorragend.
Für alle, die 2005 PE haben und Indy benötigen, hier noch ein Link zu einem hervorragenden Tutorial zur Installation von Indy in 2005 PE.
http://www.delphipraxis.net/topic53262_indykomponenten+unter+delphi+2005+pe+installieren.html

MfG Dieter


dieter1a - Di 05.02.08 18:22

Das Tool ist fertig und läuft hervorragend stabil.
Ich bin sehr froh, dass ich auf Delphi aufmerksam gemacht wurde.

Eine Frage habe ich allerdings noch.
Gibt es eine Möglichkeit das Tool, nachdem es seine GUI-Aufgabe (Registration, Anmeldung etc.) hinter sich hat automatisch zu minimieren?
Geschlossen werden darf es nicht, weil es ja die Kommunikation zwischen der 3D.exe und der Datenbank bewerkstelligt.
Es beendet sich selber, wenn die 3D-Anwendung geschlossen wird.

Wäre schön, wenn das ginge.

MfG Dieter


jaenicke - Di 05.02.08 19:58

Möglichkeiten:


dieter1a - Di 05.02.08 20:07

Recht vielen Dank Sebastian,

das hilft mir sehr.

Das Forum und Delphi sind einfach großartig.

MfG Dieter Rüstmann


dieter1a - Mi 06.02.08 12:26

Klappt hervorragend!

Jetzt habe ich mal die Suche benutzt und nach einer Möglichkeit gesucht, eine Applikation zu überwachen.
Leider wurde ich nicht fündig.

Ich möchte, dass mein Delphi-Tool kontinuierlich nachschaut, ob die 3D-Anwendung noch läuft oder nicht.
Wenn sich ein User unter seinem Nicknamen dort eingeloggt hat und die 3D-Application mit Klick auf X schließt, ist das nicht weiter problematisch.
Wenn nämlich länger als 1 Minute keine Server-Anfrage kommt, wird er automatisch in der Datenbank als offline eingetragen.
Anders ist es bei Gästen.
Beim ordnungsgemäßen ausloggen, wird auch die Anzahl der Gäste aktualisiert, andernfalls aber nicht.

Meine Frage:
Wie würde so eine Thread-Überwachung aussehen, und gibt es eventuell im Forum ein Beispielscript?

Auch könnte sich das Delphi-Programm sogar bei unsachgemäßer Beendigung der 3D-Application schließen.

Wenn das Delphi auch noch könnte, wäre ich happy ohne Ende.

Vielen Dank
Dieter


jaenicke - Mi 06.02.08 14:04

Die Forumsregeln besagen, dass neue Fragen auch in einem neuen Thread behandelt werden müssen. ;-)
Ich poste dennoch mal etwas dazu, bei Nachfragen solltest du aber einen neuen Thread aufmachen, die Thread-Überwachung hat ja nichts direkt mit der Datenbankabfrage zu tun.

Du kannst mit CreateProcess arbeiten um das andere Programm zu starten. Dann erhälst du direkt die Prozess-ID und kannst nachsehen, ob der Prozess noch läuft. Das einfachste dürfte sein, mit einem Timer zu arbeiten. Wenn das Programm nichts anderes mehr selbst machen soll, kannst du auch direkt die folgende Lösung benutzen:
http://entwickler-forum.de/showthread.php?t=36841

Muss nach dem Starten noch etwas anderes (außer dem Warten auf Beendigung) passieren, d.h. muss die Funktion zum Ausführen sofort wieder zurückkehren um weiteren Code auszuführen, dann musst du den Code aus der Schleife in einen Timer packen.


dieter1a - Mi 06.02.08 14:18

Entschuldigung bitte :oops: .

Vielen Dank für den Link.
Mal sehen ob ich damit klar komme.
Wenn nicht, mache ich einen neuen Thread auf.

Nochmal sorry und danke.
Dieter