Nachtrag zu Onlinebanking mit PHP
6. Juli 2009 von Tom
Vor über zwei Jahren hatte ich mit dem Beitrag Onlinebanking mit PHP der über einen Vortrag bei der Usergroup berichtet auch Beispielquellcode mit veröffentlicht.
In diesem Code wird auf die Onlinebanking Software Hibiscus mittels der dortigen XML-RPC Schnittstelle zugegriffen. Dafür wird die Bibliothek XML-RPC for PHP verwendet. Natürlich ist der Quellcode mitlerweile veraltet. Auch ist er nicht mit der aktuellen Hibiscus Version getestet. Und die Bibliothek ist sicherlich auch weiter gepflegt worden. Und so kann es passieren, dass beim Beispielcode Fehler beim Anlegen von Überweisungen auftreten. Doch wie damit umgehen?
Dies hat wohl dazu geführt das viele Leute die hier den Beitrag gelesen haben und sich den Quellcode gezogen haben sich nicht an mich direkt als Autor sondern an den Autor von Hibiscus gewandt. Auch in den Kommentaren ist nicht viel zu finden. So habe ich erst seit einigen Tagen die Gelegenheit mich mit dem Problem zu beschäftigen.
Leider muss ich anfügen. Nun kann wohl Hibiscus selber am wenigsten was dafür, wenn die in PHP eingesetzte XML-RPC Bibliothek einen Fehler hat. Sie kann wohl offensichtlich nicht mit Namespaces umgehen, die RPC-Response enthält aber solche. Das zeigt die Antwort auch an, es handelt sich um die XML-RPC implementierung von Apache. Es kann also zu einem Fehler kommen. Und dafür ist der Autor von Hibiscus nicht der naheliegenste Ansprechpartner. Wenn man Beispielcode nimmt, dann sollte man diesen als praktische Gelegenheit begreifen, ihn zu lesen und zu verstehen. Dazu gehört auch der Umgang mit Fehlern darin. Eigentlich sogar ein willkommener Anlass solch ein Fehler, stellt er doch quasi eine Prüfung dar, ob man verstanden hat wie es funktioniert, wenn man den Fehler löst. Ein einfaches Copy and Paste gibt einem diese Sicherheit nicht, sondern lässt einen in dem trügerischen Gefühl, ein schnelles Ergebnis erzielt zu haben. Dabei entzieht sich dieses Ergebnis der vollen eigenen Kontrolle.
Aber was tun? Da es sich bei allen Komponenten um quelloffene, Freie Software handelt drängen sich zwei Lösungen auf: Eine konkrete, der Fix oder Workaround, und eine strategischere, das Feature. Der Produzent sollte natürlich auch eingebunden sein, allerdings rate ich sehr dazu, Entwickler in freien Projekten nicht mit unausgegorenen Emails zu belästigen. Das stellt man am besten dadurch sicher, erstmal selber zu schauen, was der Auslöser des Fehlers ist. Vielleicht liegt der ja auch bei einem selber. Und was auch nervig ist: Wenn ein Benutzer einfach mal eine Mail an alle Adressen schickt die er hier oder da findet und meint: das könnte schon passen, was kümmerts mich, wenn ich andere für mich denken lassen kann.
Eine Entwicklerin, die auf einen Fehler stösst, fängt automatisch an, ihn zu analysieren.
Eine Entwicklerin, die auf einen Fehler stösst, fängt automatisch an, ihn zu analysieren. Ist die Fehlerursache bekannt, so kann sie gefixt werden. Dazu muss man meist sogar nur wenig Ahnung haben, was ein Programm da gerade macht. Ein komplettes Verständnis aller Komponenten und Hintergründe ist sicherlich hilfreich aber nicht zwingend. Heraus kommt dann ein Workaround evtl. wie dieser hier:
-
<?
-
-
function checkResponse($response=null)
-
{
-
if (!$response)
-
{
-
}
-
if ($response->faultCode())
-
{
-
if ( $response->value() == 0 )
-
{
-
$fstr=$response->faultString();
-
return;
-
}
-
".$response->faultString()."\n");
-
}
-
}
-
-
-
// …
-
-
/*
-
* Im Hauptcode steht dann:
-
*/
-
-
$value = $response->value();
-
-
if ($value != 0 )
-
$return = $value->scalarval();
-
else
-
$return="";
-
-
echo ‘<p>Überweisung wurde angelegt.</p>’;
-
-
// …
-
-
?>
Das wäre also ein Fix oder Workaround. Wie alles sind natürlich auch Fehler relativ. Konkret ist mit einem Workaround also geholfen. Und zwar schnell und einfach. Steht es hingegen an, sich um den Kern des Problems zu kümmern, so ist ein wenig mehr Arbeit und Genauigkeit von Nöten. Hier ist der Fix aber nicht umsonst, hat er doch geholfen, den Fehler einzugrenzen und die Funktionsfähigkeit wieder herzustellen.
So stellt sich erstmal die Frage warum genau der Fehler zu Tage tritt und warum der Fix nun funktioniert. Die Eingrenzung des Fehlers auf seine ausschlaggebende Ursache. Bei diesem Beispiel ist es relativ einfach mit der Fehlerursache. Auch das Protokoll von XML-RPC ist relativ offen, den es basiert auf (recht einfachen) XML Dokumenten, die per HTTP ausgetauscht werden. So ist zum debuggen mittels PHP das XML der Antwort einsehbar indem der String ausgegeben wird:
-
<?xml version="1.0" encoding="UTF-8"?>
-
<methodResponse
-
xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
-
<params>
-
<param>
-
<value>
-
<ex:nil/>
-
</value>
-
</param>
-
</params>
-
</methodResponse>
Der Fehler tritt hier auf, weil die PHP XML-RPC Bibliothek nichts mit dem Rückgabewert “<ex:nil/>” anfangen kann. Nun stellt sich die Frage, wie damit umgehen? Wo genau liegt der Fehler, in der PHP-Bibliothek oder in der Implementierung in der Java-Bibliothek von Apache? Wenns um Bibliotheken geht ist das oft ein Zeichen dafür, dass es sich hier um eine grundlegendere Frage handelt. Und das eine Lösung aufwendiger und auch problematischer sein kann. Dies aus zwei Gründen:
Zum einen werden Bibliotheken von vielen Programiererinnen und Anwendern in unterschiedlichen Anwendungen genutzt dessen allen Bedürfnisse eine Bibliothek unter einen Hut bekommen muss. Eine “Fehlerbehebung” die zu nicht erwartenen Ergebnissen führt kann zum Beispiel bestehende Anwendungen gefährden.
Zum anderen, weil wenn ein Fehler gefunden wird, ein Fehlerbericht an das Projekt der Bibliothek gemacht werden sollte. Dazu muss erstmal rausgefunden werden, wie dies gemacht wird und es ist oft nicht klar, wie schnell ein Fehler im Projekt behoben wird, nachdem er gemeldet wird.
Mein Code, Dein Code, unser Code.
In der Programmierung spricht man hier oft vom “Upstream”. Ich erstelle für die lokale Kopie meiner Bibliothek einen Patch, der das gewünschte Feature implementiert. Das Feature für die PHP-Bibliothek ausführlich formuliert wäre hier: Die Unterstützung des ex:nil Rückgabewertes zwecks Kompabilität zur Apache XML-RPC Implementierung.
Läuft der Patch bei mir und bin ich sicher, dass das auch für andere AnwenderInnen der Bibliothek Sinn macht, upstreame ich den Patch, in dem ich den dem Bibliotheksprojekt zur Verfügung stelle. Meist wird darüber diskutiert was für und was gegen den Patch spricht und der Patch entsprechend modifziert resp. erweitert. Wird der Patch akzeptiert, landet er meist im nächsten Release des Projektes.
Keep Up the Upstream.
Damit ist dann allen geholfen. Übrigens sind viele Entwicklerinnen dann für Feedback dankbar, wenn es um eine reale Fehlerlösung geht. So hat der Entwickler im Hibiscus Projekt sicherlich kein Interesse daran, PHP-Programmierern bei der Fehlersuche zu helfen, selbst wenn er ein ganz lieber ist und es mit den Anfragen auch generell recht freundlich hält. Hätte die Schnittstelle auf seiner Seite einen Fehler würden sich warscheinlich schon recht viele Leute beschwert haben… . Das XML-RPC for PHP Projekt hingegen hat aber vielleicht ein echtes Interesse daran, die Bibliothek kompatibel mit der Apache Implementierung zu halten. Jeder Fehler ist eine Chance ein Programm zu verbessern. Keep Up the Upstream.
PHP Usergroup Frankfurt am Main (PHPUGFFM)
