EF Confirm

Sebbo

Well-known member
ID: 7919
L
24 Mai 2007
185
14
Hallo

Ich habe eine Frage zu Exportforce.
Bin grade dabei, ein erstes kleines Loseprojekt zu machen und wühle mich grade durch die EF-API. Und da lese ich bei EF Confirm
Ab und zu kommt es vor, dass EF aufgrund einer DB-Überlastung nicht antwortet (Timeout). Um festzustellen, ob die Transaktion erfolgreich durchgeführt wurde oder nicht, kann man jeder kritischen Anfrage (send.php, get.php, efsend.php) eine eindeutige Identifikation (Code) mitgeben, und mittels efconfirm.php innerhalb von 48 Stunden die zugehörige Rückgabe jederzeit abfragen. Als Transaktions-Code kann ein beliebiger String verwendet werden (max. 200 Zeichen). Achten Sie jedoch darauf, keinen Code doppelt zu verwenden, da sonst eine eindeutige Identifikation der Transaktion nicht möglich ist. Empfehlenswert wäre z.B. der md5()-Hash von microtime() (oder einfach Ihre interne TransaktionsID). Liefert efconfirm.php kein Ergebnis zu einem bestimmten Code zurück (1089), so ist die zugehörige Transaktion entweder länger als 48 Stunden her, es wurde kein korrekter Code übergeben, oder die Transaktion wurde seitens EF definitiv nicht durchgeführt!

Bedeutet das, dass selbst wenn z.B. ein send.php oder get.php als Rückgabecode 1001 (Alles ok) ausgibt, die Transaktion doch nicht funktioniert haben muss? Dann wäre der Rückgabecode ja ziemlich unbrauchbar (zumindest was den Status 1001 angeht) und ich müßte jede Transaktion im Nachhinein nochmals überprüfen.
 
nein, das bedeutet, das gar kein rückgabecode kommt (timeout), aber die transaktion trotzdem durchgeführt wurde.
 
Ich muss also nur in dem Fall prüfen, wo ich bei der eigentlichen Transaktion keine Rückgabe bekomme. Kann ich diese Prüfung sofort durchführen oder muss ich dazu eine gewisse Zeit warten?

Beispiel:
PHP:
$adresse = "https://www.klamm.de/engine/lose/send.php?ef_id=...&code=$code";
$fp=@fopen($adresse,"r");
if ($fp)
{
	$line=@fgets($fp,1000);
	$werte_array=split("[|]",$line,5);
	return $werte_array[0];
}
else
{
	// Es könnte sein, dass die Buchung trotzdem ausgeführt wurde.
	// Jetzt sofort mit confirm testen, ob trotzdem ausgeführt?
       // Oder diese Prüfung später (z.B. per Cronjob) durchführen lassen?
}
 
naja... sofort prüfen könnte fehlschlagen -> wenn es gerade zu einem timieout gekommen ist, dann ist es wahrscheinlich, daß es direkt danach wieder zu einem timeout kommt.

ich habe es mal so benutzt:


  1. user zahlt lose aus
  2. ef -> timeout
  3. internes userguthaben wird reduziert
  4. user hat in der transaktionsliste einen link, der die transaktion überprüft
  5. bei klick wird geprüft, ob die transaktion erfolgreich war und die lose dann entsprechend verbucht
wichtig ist nur, daß wenn es zu einem timeout kommt, dieses abzufangen und nicht einfach davon ausgehen, daß keine transaktion gelaufen ist.

ich hatte mal den fall, daß ein user sein guthaben mehrfach auszahlen konnte, weil es zu einem timeout kam und das script davon ausgegangen ist, daß keine ef buchung stattgefunden hat.
 
Ich würde dir tleilax' EF-Class empfehlen:

https://tleilax.loseinsel.de/ef/

Nicht unbedingt; da gibt es Verbesserungsmöglichkeiten bzw. einen echten Bug.

Ich hatte tleilax eine PN geschrieben, aber das hat er wohl noch nicht eingebaut.

Hi,

ich benutze für ein neues Projekt auch deine EF-Klasse. Dabei ist mir folgendes aufgefallen:

1) tcode
Ich fände es praktischer, wenn ich optional bei send/get selbst einen Transcode angeben kann. Dann könnte ich vorher schon den Code in eine Tabelle eintragen, die Anfrage absenden und danach den Eintrag löschen oder ändern. Falls nämlich während der EF-Anfrage mein Server abstürzt, komme ich nicht mehr dazu, den Transcode einzutragen, falls EF nicht erreichbar ist.

Und überhaupt ...

PHP:
      $kret = $this->_efQuery($efQuery);
      if ($kret===false)
        return false;
      $kres = explode('|', $kret[0]);
      $this->_eflose = $kres[1];
      $this->_userlose = $kres[2];
      $this->_efcalls = $kres[4];
      return ($kres[0]!=1001)?false:$tcode;
Wenn klamm nicht erreichbar ist, bekomme ich false. Wenn EF erreichbar ist und ein Fehler aufgetreten ist (!=1001) bekomme ich ebenfalls false. Und wenn alles gut ging, bekomme ich den Transcode :hö: ? Genau in dem Fall brauche ich den Code nicht. Ich brauche ihn, wenn EF nicht erreichbar ist oder nicht antwortet. Dann muss ich prüfen, ob meine Anfrage vielleicht doch durchkam und nur keine Antwort geschickt wurde.

Ich habe mir selbst geholfen, indem ich bei getlose und sendlose den Transcode selbst übergebe.

2) confirm
Hm, das sieht mir wie ein echter Bug aus ;) .

PHP:
      if ($kres[0]!=1001)
        return false;
      $timestamp = $kret[2];
      $tmpinfo = explode('|', $kret[1]);
      return $tmpinfo[0];
Du hast da folgendes nicht bedacht: wenn ein Transcode bei EF nicht existiert, kommt direkt 1089.

Returncodes:
1001 // Alles OK
1002 // EF Account existiert nicht
1003 // EF Passwort falsch
1089 // Transaktions-Code nicht vorhanden
1098 // EF Account ist gesperrt
1099 // Unbekannter Fehler
Da fehlt also
PHP:
      if ($kres[0]==1089)
        return 1089;
Mit deiner Version bekomme ich false, wenn EF immer noch nicht erreichbar ist und auch false, wenn der Code nicht existiert. 1089 bekomme ich in keinem Fall.

3) Art der Fehlers
Es gibt einen Unterschied zwischen "regulären" und "fatalen" Fehlern. Beispiel: ich mache getlose() und bekomme einen Fehler (false). Jetzt möchte ich ja gern wissen, was das für ein Fehler war: "EF antwortet nicht" oder z.b. "Losepasswort falsch". Im 1. Fall muss ich den Code speichern und später abfragen. Im 2. Fall kann ich einfach sagen "LosePW falsch" und muss nichts weiter tun. Da fehlt also sowas wie "is_regular_error". Bei Fehlern von 1002-1098 sagt die Funktion "JA", dann kann ich einfach den Fehler durchreichen. Bei 1099 oder -99 muss ich aktiv werden, weil ich da nicht weiß, ob die Trans nun wirklich durchgeführt wurde oder nicht. Ohne eine solche Funktion muss ich alle Codes einzelne abfragen, und die Funktionalität gehört "eigentlich" in die Klasse - denke ich ;) .

Na gut, ich hab mir das alles nach meinen Vorstellungen angepasst, aber vielleicht kannst du ja deine Klasse auch ändern ;) .
 
:oops: :shifty: Die PN liegt noch als Verbesserungsvorschlag rum, wenn ich mich wieder mal an die Klasse setze. Ich will die schon lange auch mal auf PHP5 umschreiben, aber manchmal muss man erstmal Zeit und Elan zusammenbringen können, damit sowas klappt. :ugly: