PHP5 und BiPRO Teil II

Ich stecke aktuell mal wieder in einem BiPRO Projekt und stoße hier und da auf ein paar Schwierigkeiten bei der Umsetzung. Da die Umsetzung mit PHP5 sehr umfangreich ist und der Support seitens der Versicherer mit Hinblick auf PHP5 sehr minimal ist, möchte ich Euch hier an ein paar Lösungsansätzen teilhaben lassen.

Die hier gezeigten Code Beispiele basieren auf einer objektorientierten Programmierung mit PHP5 und den in PHP5 enthaltenen Soap Objekten. Es werden also keine XML Schemata als String hardcodiert und dann versendet. Sämtliche XML Schemata werden allein vom PHP Soap Client anhand der vom jeweiligen Versicherer gelieferten WSDL Datei erstellt.

Heute bin ich im Zusammenhang mit der BiPRO Norm auf folgenden Fehler gestoßen:

The type definition cannot be abstract for element ns3:Partner

Nach einer eingehenden Prüfung des XML Schemas stellte sich heraus, dass der Versicherer bei der Tarifierung den Knoten „Partner“ mit einer Typen Definition ausgestattet hat. Dies geht nicht aus den XSD Definitionen hervor, sondern ist lediglich in den Beispiel Requests des jeweiligen Versicherers zu sehen.

Hat man die Objekte der BiPRO Norm (Complex Types) vernünftig für PHP aufgelöst, sehen die zu verwendenden Objekte für den Partner Knoten in etwa so aus:

/**
 * Struct CT_Person
 */
class CT_Person extends CT_Partner {
    protected $Vorname = null;
    protected $Geburtsdatum = null;
    protected $Geschlecht = null;
    protected $Titel = null;
    protected $Geburtsort = null;
    protected $Stsangehoerigkeit = null;
    protected $Familienstand = null;
    protected $Adelspraedikat = null;
    protected $Geburtsname = null;
    protected $Geburtsland = null;
    protected $InDeutschlandAnsaessigSeit = null;
    protected $Steueridentifikationsnummer = null;
    protected $Ausweis = null;
    protected $GesetzlicheKrankenversicherung = null;
    protected $Einkommenssteuer = null;
    protected $Berufstaetigkeit = null;
    protected $Einkommen = null;
    protected $Haushalt = null;
    protected $Ausbildung = null;
    protected $Gesundheitsdaten = null;

    public function __construct( ... ) { ... }
}

/**
 * Struct CT_Partner
 */
abstract class CT_Partner {
    protected $Anrede = null;
    protected $Name = null;
    protected $Namenszusatz1 = null;
    protected $Namenszusatz2 = null;
    protected $PartnernummerVU = null;
    protected $PartnernummerVM = null;
    protected $Vorsteuerabzugsberechtigt = null;
    protected $PartnerID = 0;
    protected $Anschrift = null;
    protected $ZusaetzlichePartnerdaten = null;
    protected $Kommunikationsverbindung = null;
    protected $Bankverbindung = null;
    protected $HandeltAufRechnungVon = null;
    protected $Gruppenvertragspartner = null;
    protected $Partnerbeziehung = null;
    protected $Vertrauensperson = null;

    public function __construct( ... ) { ... }

    public function __set($name, $value) {
        $this->{$name} = $value;
    }

    public function __get($name) {
        return isset($this->{$name}) ? $this->{$name} : null;
    }

Verwendet man diese Objekte nun direkt für den Soap Client könnte Euer Code wie folgt aussehen:

try {
    $client = new SoapClient('DeineWsdlDatei.wsdl');
    $params = new CT_QuoteRequest(
        ...
        new CT_Person(
            ...
        )
        ...
    );
    $response = $client->getQuote($params);
} catch (SoapFault $e) {
    // error handling
}

Unter normalen Umständen ist es vollkommen ausreichend, wenn man die Objekte direkt so übergibt, wie ich es im oben genannten Beispiel getan habe. Leider ist es aber in meinem Fall so, dass der Versicherer dem Partner Knoten noch ein Attribute „type“ mitgegeben hat, ohne das das komplette XML Schema invalide ist. Wenn ich den Request also wie oben beispielhaft dargestellt absende, bekomme ich folgendes XML Schema:


...

Ein reiner Knoten ohne Attribute. Wie gebe ich also ohne großen Aufwand dem Knoten Partner das vom Versicherer verlangte Type Attribut mit auf den Weg? Wie schon im vorhergehenden Teil beschrieben, ist es gar nicht so schwer BiPRO Webservices Attribute mit auf den Weg zu geben. In diesem Fall ist es sogar noch weitaus einfacher. Folgendes Beispiel zeigt, wie man ein Attribut in einem Knoten realisieren kann, ohne dabei die Objekte, welche die BiPRO Norm für PHP nachbilden, erweitern zu müssen.

try {
    $client = new SoapClient('DeineWsdlDatei.wsdl');
    $params = new CT_QuoteRequest(
        ...
        new SoapVar(
            new CT_Person(
                ...
            ),
            SOAP_ENC_OBJECT,
            'CT_Person',
            'http://www.bipro.net/namespace/partner'
        )
        ...
    );
    $response = $client->getQuote($params);
} catch (SoapFault $e) {
    // error handling
}

Das daraus resultierende XML Schema sieht dann wie folgt aus:


...

Somit ist das XML Schema auch valide und wird vom Webservice des Versicherers auch angenommen. Das SoapVar Objekt funktioniert hier theoretisch als Mantel und so ist man in der Lage für diesen spezifischen XML Knoten einen neuen Typen und einen gesonderten Namespace anzugeben.

Warum eine objektorientierte Umsetzung für BiPRO?

Der Vorteil einer objektorientierten Umsetzung liegt auf der Hand: die Wiederverwendbarkeit von Programmcode. Ich kann mit den PHP Objekten, welche die Structs der BiPRO Norm repräsentieren sehr viel effezienter arbeiten. Während ich bei den ersten BiPRO Projekten noch lange String-Verkettungen in den PHP Code setzte, und für jeden Request quasi die gleichen Strings erneut in den Code schrieb, kann ich die jetzigen Objekte einfach neu aufrufen. Der PHP Code ist sehr viel genauer und wartungsärmer und durch die seit PHP5 vorhandene SOAP Erweiterung erstellt das XML Schema voll automatisch.

Ein großer Nachteil bleibt aber die nicht einheitliche Umsetzung der Versicherer. Während die von mir zuvor umgesetzten Anbindungen an Webservices von Versicherungen keinerlei Probleme mit Attributen in einem Knoten hatten, stoße ich nun auf diese Variante eines BiPRO Webservices.

Fragen? Aufträge?

Nutzt einfach die Kommentarfunktion für Eure Fragen. Ihr kommt mit der BiPRO Norm oder der Anbindung eines Webservices auf Basis der BiPRO Norm nicht zurecht? Meldet Euch einfach und wir schauen gemeinsam, was man tun kann, wenn der BiPRO Support bei PHP Fragen mal wieder nicht helfen kann.

5 Gedanken zu „PHP5 und BiPRO Teil II“

    • Hallo Marcel,

      es gibt PHP Bibliotheken, die die WSDL Datei und die damit zusammenhängenden Definitionen in den XSD Dateien parsen und daraus automatisch die entsprechenden Klassen definieren. Allerdings sind diese Bibliotheken sehr ungenau. Teilweise werden Vererbungen und Abstraktionen nicht erkannt. Namespaces, Verzeichnisstrukturen oder gar Type Hinting für eine genaue Programmierung mit PHP7 sind dann auch eher die Ausnahme.

      Aus Erfahrung heraus bin ich immer besser mit selbst programmierten Klassen gefahren. Kommt aber auch immer ein bisschen darauf an, wie genau Du die Umsetzung haben möchtest. Wenn Dir automatisch erstellte Klassen ausreichen, nutze eine dieser Bibliotheken. Für ein umfassenderes Projekt, welches die BiPRO Complex und Simple Types für mehrere Bereiche benutzt, würde ich die Programmierung per Hand wählen.

      Eine der erwähnten Bibliotheken wäre z.B. WSDL2PHPGenerator (https://github.com/wsdl2phpgenerator/wsdl2phpgenerator)

      Ich hoffe ich konnte Dir ein wenig weiter helfen.

      Viele Grüße und vor allem viel Glück,
      Marcel

      Antworten
  1. Danke für Deine Rückmeldung!
    Ich steh mit Birro noch ganz am Anfang!
    Ich werd es erstmal so unkompliziert wie es geht machen und den Komfort dann erst mit Automatismen verbessern, wenn ich mehr im Thema stecke. Ich darf erstmal Daten migrieren und schlage mich durch die tausende Pfade der wuchtigen BiPro-Doku mit Ihren XSD-Dateien. Eigentlich ist das Ganze echt gut durchdacht, also von BiPro selbst.
    Nur die XML zu erstellen, da bin ich voll der Einsteiger. Ich bin echt Dankbar für Deine Beiträge. Im Netz bist Du fast der Einzige, wo ich Anhaltspunkte fand.

    Antworten

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.